leakcanary android tutorial




Atividade que vazou janela que foi originalmente adicionada (20)

A melhor solução é colocar isso antes de mostrar progressbar ou progressDialog

if (getApplicationContext().getWindow().getDecorView().isShown()) {

  //Show Your Progress Dialog

}

Qual é esse erro e por que isso acontece?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.[email protected] that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.[email protected] that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at dalvik.system.NativeStart.main(Native Method)

A solução é chamar dismiss() na caixa de Dialog você criou na viewP.java:183 antes de sair da Activity , por exemplo, em onPause() . Todas as Window e Dialog devem ser fechadas antes de deixar uma Activity .


As exceções vazadas na janela têm dois motivos:

1) mostrando a caixa de diálogo quando o Contexto de Atividades não existe, para resolver isso, você deve mostrar a caixa de diálogo somente se tiver certeza de que a Atividade existe:

if(getActivity()!= null && !getActivity().isFinishing()){
        Dialog.show();
}

2) não dispense o diálogo adequadamente, para resolver use este código:

@Override
public void onDestroy(){
    super.onDestroy();
    if ( Dialog!=null && Dialog.isShowing() ){
        Dialog.dismiss();
}
}

As respostas para essa pergunta estavam todas corretas, mas um pouco confusas para eu entender o porquê. Depois de brincar por cerca de 2 horas a razão para esse erro (no meu caso) me atingiu:

Você já sabe, da leitura de outras respostas, que o X has leaked window [email protected][] erro significa que uma caixa de diálogo estava aberta quando seu aplicativo foi fechado. Mas por que?

Pode ser que seu aplicativo tenha falhado por algum outro motivo enquanto sua caixa de diálogo estava aberta

Isso leva ao fechamento do seu aplicativo devido a algum bug no seu código, o que faz com que o diálogo permaneça aberto ao mesmo tempo em que o aplicativo é fechado devido a outro erro.

Então, olhe através da sua lógica. Resolva o primeiro erro e, em seguida, o segundo erro resolver-se-á

Um erro causa outro, o que causa outro, como DOMINOS!


Esta não é a resposta para a pergunta, mas é relevante para o tópico.

Se a atividade tiver definido um atributo no Manifesto

 android:noHistory="true"

depois de executar onPause (), o contexto da atividade é perdido. Então, toda a visão usando esse contexto pode dar esse erro.


Eu acionei este erro erroneamente chamando hide() vez de dismiss() em um AlertDialog .


Eu estava tendo o mesmo problema e encontrei esta página, e enquanto minha situação era diferente, eu chamei de finish de um bloco if antes de definir a caixa de alerta.

Então, simplesmente chamar dismiss não funcionaria (como não foi feito ainda), mas depois de ler a resposta de Alex Volovoy e perceber que era a caixa de alerta causando isso. Eu tentei adicionar uma declaração de retorno logo após o término dentro daquele bloco e que resolveu o problema.

Eu pensei que uma vez que você ligasse para terminar, pararia tudo e terminaria ali mesmo, mas isso não acontece. Parece que vai até o final do bloco de código em que está e termina.

Então, se você quer implementar uma situação onde às vezes ele termina antes de fazer algum código, você tem que colocar uma declaração de retorno logo após o final ou ele vai continuar e agir como se o final fosse chamado no final do código. bloco de código não onde você ligou. É por isso que eu estava recebendo todos esses erros estranhos.

private picked(File aDirectory){
     if(aDirectory.length()==0){
        setResult(RESULT_CANCELED, new Intent()); 
        finish(); 
        return;
    }
     AlertDialog.Builder alert= new AlertDialog.Builder(this); // Start dialog builder
     alert
        .setTitle("Question")
        .setMessage("Do you want to open that file?"+aDirectory.getName());
    alert
        .setPositiveButton("OK", okButtonListener)
        .setNegativeButton("Cancel", cancelButtonListener);
    alert.show();
}

Se você não colocar o retorno logo depois que eu liguei para terminar lá, ele vai agir como se você tivesse chamado depois do alert.show(); e, portanto, diria que a janela vazou ao terminar logo após a exibição da caixa de diálogo, mesmo que esse não seja o caso, ela ainda acha que é.

Eu pensei em adicionar isso aqui, já que isso mostra que o comando terminar agiu de forma diferente, então eu pensei que sim e eu acho que há outras pessoas que pensam da mesma forma que eu antes de descobrir isso.


Eu tive a mesma mensagem de erro obscura e não tinha ideia do porquê. Dada pistas das respostas anteriores, mudei minhas chamadas não-GUI para mDialog.finish () para ser mDialog.dismiss () e os erros desapareceram. Isso não afetava o comportamento do meu widget, mas era desconcertante e poderia estar sinalizando um vazamento de memória importante.


Geralmente, este problema ocorre devido ao diálogo de progresso: você pode resolver isso usando qualquer um dos seguintes métodos em sua atividade:

 // 1):
          @Override
                protected void onPause() {
                    super.onPause();
                    if ( yourProgressDialog!=null && yourProgressDialog.isShowing() )
                  {
                        yourProgressDialog.cancel();
                    }
                }

       // 2) :
         @Override
            protected void onDestroy() {
                super.onDestroy();
                if ( yourProgressDialog!=null && yourProgressDialog.isShowing()
               {
                    yourProgressDialog.cancel();
                }
            }

Ignorar o diálogo quando a atividade destruir

@Override
protected void onDestroy()
{
    super.onDestroy();
    if (pDialog!=null && pDialog.isShowing()){
        pDialog.dismiss();
    }
}

Isso pode acontecer se você tiver um erro na função doInBackground() e tiver esse código.

Tente adicionar o diálogo finalmente. Na primeira vez, verifique e corrija a função doInBackground()

protected void onPreExecute() {
     super.onPreExecute();
     pDialog = new ProgressDialog(CreateAccount.this);
     pDialog.setMessage("Creating Product..");
     pDialog.setIndeterminate(false);
     pDialog.setCancelable(true);
     pDialog.show();

 }

 protected String doInBackground(String...args) {
     ERROR CAN BE IS HERE
 }

 protected void onPostExecute(String file_url) {
     // dismiss the dialog once done
     pDialog.dismiss();

Isso poderia ajudar.

if (! isFinishing()) {

    dialog.show();

    }

No meu caso, o motivo foi que esqueci de incluir uma permissão no arquivo de manifesto do Android.

Como eu descobri? Bem, assim como o @Bobby diz em um comentário abaixo da resposta aceita, basta ir até seus registros e você verá o primeiro motivo ou evento que realmente gerou a Exceção. Aparentemente, a mensagem "Atividade vazou janela que foi originalmente adicionada" é apenas uma exceção que resultou de qualquer que seja a primeira exceção.


O erro "A Activity has leaked window that was originally added... " ocorre quando você tenta mostrar um alerta após a finished efetiva da Activity .

Você tem duas opções AFAIK:

  1. Repense o login de seu alerta: chame dismiss() na dialog antes de realmente sair de sua atividade.
  2. Coloque o dialog em um segmento diferente e execute-o nesse thread (independente da activity atual).

Recentemente, enfrentei o mesmo problema.

A razão por trás deste problema é que a atividade está sendo fechada antes do diálogo ser dispensado. Existem várias razões para que isso aconteça. Os mencionados nos posts acima também estão corretos.

Eu entrei em uma situação, porque no segmento, eu estava chamando uma função que estava lançando exceção. Por causa do qual a janela estava sendo descartada e, portanto, a exceção.


Se você estiver usando o AsyncTask , provavelmente essa mensagem de log pode ser enganosa. Se você procurar em seu log, você pode encontrar outro erro, provavelmente um em seu método doInBackground() do seu AsyncTask , que está fazendo sua Activity atual explodir, e assim uma vez que o AsyncTask voltar ... bem, você sabe o descansar. Alguns outros usuários já explicaram que aqui :-)


Tive o problema de terminar uma atividade quando um ProgressDialog ainda era exibido.

Então, primeiro esconda o diálogo e termine a atividade.


Você está tentando mostrar uma caixa de diálogo depois de sair de uma atividade.

[EDITAR]

Esta questão é uma das principais pesquisas no google para o desenvolvedor android, portanto, Adicionando alguns pontos importantes de comentários, o que pode ser mais útil para o futuro investigador, sem ir em profundidade da conversa de comentários.

Resposta 1 :

Você está tentando mostrar uma caixa de diálogo depois de sair de uma atividade.

Resposta 2

Esse erro pode ser um pouco enganador em algumas circunstâncias (embora a resposta ainda seja completamente correta) - ou seja, no meu caso uma exceção não tratada foi lançada em um AsyncTask, que causou o desligamento da Atividade, então uma caixa de diálogo de progresso aberta causou essa Exceção. a exceção 'real' foi um pouco mais cedo no log

Resposta 3

Chame dismiss () na instância Dialog que você criou antes de sair de sua Activity, por exemplo em onPause () ou onDestroy ()


Você tem que fazer Progressdialog objeto Progressdialog no método AsyncTask do AsyncTask e deve dismiss lo no método onPostExecute .


A melhor solução é apenas adicionar diálogo no diálogo try catch and dismiss quando ocorrer uma exceção

Basta usar abaixo do código

 try {
        dialog.show();
    } catch (Exception e) {
        dialog.dismiss();
    }




dialog