【问题标题】:android.view.WindowLeaked on Asyctaskandroid.view.WindowLeaked on Asynctask
【发布时间】:2016-10-01 11:38:33
【问题描述】:

我在尝试运行 asynctask 时遇到问题。有时会出现错误,例如,如果我运行 asynctask 20 次,错误会出现 1 或 2。 我认为问题出在 ProgressDialog 上(在没有 Dialog 运行时尝试关闭),但我无法解决。

错误日志说:

E/WindowManager: android.view.WindowLeaked: Activity com.app.GestionarTurnos has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{26d38b91 V.E..... R......D 0,0-160,180} that was originally added here
                                                                           at android.view.ViewRootImpl.<init>(ViewRootImpl.java:375)
                                                                           at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
                                                                           at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
                                                                           at android.app.Dialog.show(Dialog.java:298)
                                                                           at com.app.CalcularHorariosDisponiblesComplejo$CalcularHorariosComplejoAsyncTask.onPreExecute(CalcularHorariosDisponiblesComplejo.java:110)

这是我的来自 CalcularHorariosDisponiblesComplejo.java 的异步任务代码:

public MyAsyncTask(Context context, String idComplejoSeleccionado, String idCancha, String nombreComplejo, String idUsuarioComplejo, String idPais, String dia, String mes, String anio) {
        super();
        this.context = context;
        this.idComplejoSeleccionado = idComplejoSeleccionado;
        this.idCanchaSeleccionada = idCancha;
        this.nombreComplejo = nombreComplejo;
        this.idUsuarioComplejo = idUsuarioComplejo;
        this.idPais = idPais;
        this.dia = Integer.parseInt(dia);
        this.mes = Integer.parseInt(mes);
        this.anio = Integer.parseInt(anio);

        Calendar cl = Calendar.getInstance(TimeZone.getTimeZone(String.valueOf(65)));
        cl.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dia));
        cl.set(Calendar.MONTH, Integer.parseInt(mes));
        cl.set(Calendar.YEAR, Integer.parseInt(anio));
        this.dayOfWeek = cl.get(Calendar.DAY_OF_WEEK);

        dialog = new ProgressDialog(context, R.style.ProgressDialogTheme);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        this.dialog.show();
    }
    protected String doInBackground(String... args) {
        jsonCalcularHorariosComplejo = null;
        fechaSeleccionada = (String.valueOf(anio)) + "-" + (String.valueOf(mes + 1)) + "-" + (String.valueOf(dia));

        try {
            jsonCalcularHorariosComplejo = JSONParser.readJsonFromUrl(url.concat(fechaSeleccionada+"&idCancha="+idCanchaSeleccionada+"&idUsuario="+idUsuarioComplejo+"&idComplejo="+idComplejoSeleccionado+"&dayOfWeek="+dayOfWeek+"&idPais="+idPais));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
    protected void onPostExecute(String file_url) {
        if (!esCancelado) {
            if(jsonCalcularHorariosComplejo == null){
                Toast toast = Toast.makeText(context, "Not possible connect with the server. Try it again", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
                toast.show();
                Intent intent = new Intent(context, SeleccionarCanchaComplejo.class);
                intent.putExtra("idComplejo", idComplejoSeleccionado);
                intent.putExtra("nombreComplejo", nombreComplejo);
                intent.putExtra("idPais", idPais);
                intent.putExtra("idUsuarioComplejo", idUsuarioComplejo);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                context.startActivity(intent);
                ((Activity)context).finish();
            }
            else{
                try {
                    // Verifica que se cargaron datos
                    int success;
                    success = jsonCalcularHorariosComplejo.getInt(TAG_SUCCESS);
                    if (success == 1) {
                        diaHoy = Integer.parseInt(jsonCalcularHorariosComplejo.getString(TAG_DIAHOY));
                        mesHoy = Integer.parseInt(jsonCalcularHorariosComplejo.getString(TAG_MESHOY));
                        anioHoy = Integer.parseInt(jsonCalcularHorariosComplejo.getString(TAG_ANIOHOY));
                        horaActual = jsonCalcularHorariosComplejo.getString(TAG_HORA);
                        todosLosTurnos = jsonCalcularHorariosComplejo.getJSONArray(TAG_TODOS_LOS_TURNOS);

                        for (int i = 0; i < todosLosTurnos.length(); i++) {
                            turnoAux = todosLosTurnos.getJSONObject(i);
                            // Guardo en variables los datos del objeto
                            String hora = turnoAux.getString(TAG_HORA);
                            int canchaFK = Integer.parseInt(turnoAux.getString(TAG_CANCHAFK));
                            int usuarioFK = Integer.parseInt(turnoAux.getString(TAG_USUARIOFK));
                            int reservado = Integer.parseInt(turnoAux.getString(TAG_RESERVADO));
                            String fecha = turnoAux.getString(TAG_FECHA);
                            String nombreAuxiliar = turnoAux.getString(TAG_NOMBREAUXILIAR);
                            int noAsistio = Integer.parseInt(turnoAux.getString(TAG_NOASISTIO));
                            String fechaDeReserva = turnoAux.getString(TAG_FECHADERESERVA);
                            String telefonoAux = turnoAux.getString(TAG_TELEFONO);
                            String estado = turnoAux.getString(TAG_ESTADO);
                            Turno turno = new Turno(hora, canchaFK, usuarioFK, reservado, fecha, nombreAuxiliar, noAsistio, fechaDeReserva, telefonoAux, estado);
                            todosMisTurnos.add(turno);
                        }
                    }
                }catch (JSONException e) {
                    e.printStackTrace();
                }
                Intent intent = new Intent(context, Gestionar.class);
                intent.putExtra("todosMisTurnos", (ArrayList<Turno>) todosMisTurnos);
                intent.putExtra("idComplejo", idComplejoSeleccionado);
                intent.putExtra("idCancha", idCanchaSeleccionada);
                intent.putExtra("nombreComplejo", nombreComplejo);
                intent.putExtra("idUsuarioComplejo", idUsuarioComplejo);
                intent.putExtra("idPais", idPais);
                intent.putExtra("dia", String.valueOf(dia));
                intent.putExtra("mes", String.valueOf(mes));
                intent.putExtra("anio", String.valueOf(anio));
                intent.putExtra("diaHoy", String.valueOf(diaHoy));
                intent.putExtra("mesHoy", String.valueOf(mesHoy));
                intent.putExtra("anioHoy", String.valueOf(anioHoy));
                intent.putExtra("horaActual", horaActual);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                ((Activity)context).finish();
                context.startActivity(intent);
            }
            if (dialog.isShowing()) {
                dialog.dismiss();
            }
        }
    }
}

当我转到 java:110 行中的错误时,是这一行(预执行): this.dialog.show();

有人可以帮助我吗?

【问题讨论】:

  • 这个Context参数是Activity吗?
  • 删除条件以关闭对话框并确保 dialog.dismiss();onPostExecute();的第一条语句中>

标签: android android-asynctask progressdialog


【解决方案1】:

如果你有多个 AsyncTask 则启动 Progress Dialog 机制将被更改为

当您有多个异步任务并逐步执行时,首先不要在 onPreExceute()onPostExecute() 中定义 dialog.show()

而不是尝试实现这些东西

在主线程中启动进度对话框

      Start Asynctask 1
      Start Asynctask 2

      Start Asynctask 20

在 Asynctask 20 的响应中关闭 mainThread 中的进度对话框

中间不需要启动和停止asynctask

会有用的

编码愉快!!!

【讨论】:

  • 我只有一项任务。您还可以从发送上下文的其他活动中调用异步任务
  • 所以我不明白亲爱的你遇到了什么问题?
【解决方案2】:
if (dialog.isShowing()) {
            dialog.dismiss();
        }

这就是问题所在。将它放在 onPostExecute() 的开头

【讨论】:

  • 还是有问题
【解决方案3】:

伙计,您正在杀死活动,然后尝试关闭对话框,首先在活动中执行所有操作,然后在最后杀死您的活动。 首先是这个:

        context.startActivity(intent);
    }
    if (dialog.isShowing()) {
        dialog.dismiss();
    }

只有这样

((Activity)context).finish();

因为现在你杀死了活动,然后你试图在不存在的活动中关闭对话框。

【讨论】:

  • 我想你多次调用这个任务?如果是这样,您必须计算您调用的某个值的实例(开始时增加,停止时减少) - 并且仅在最后一个实例完成时才终止活动
【解决方案4】:

您的问题在这里得到了很好的描述:

Activity has leaked window that was originally added

一般来说,我建议您注意AsyncTasks 执行代码而不是Activity,例如显示对话框或完成它,因为它在AsyncTask 和@987654325 之间建立了牢固的联系@。而且,由于任务与活动异步,因此可能会出现一些问题,例如,当AsyncTask 完成其后台工作时Activity 不再存在,或者当多个AsyncTasks 从同一个@987654329 分派时@同时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-20
    • 2014-08-24
    • 2014-08-04
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多