Die Aktivität hat ein Fenster verloren, das ursprünglich hinzugefügt wurde


1163

Was ist dieser Fehler und warum passiert er?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 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.PhoneWindow$DecorView@44c46ff0 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)

6
Der andere Klassiker ist, wenn sich die Ausrichtung ändert: stackoverflow.com/questions/1111980/…
rds

Antworten:


1560

Sie versuchen, einen Dialog anzuzeigen, nachdem Sie eine Aktivität beendet haben.

[BEARBEITEN]

Diese Frage ist eine der häufigsten Suchanfragen bei Google für Android-Entwickler. Daher werden einige wichtige Punkte aus Kommentaren hinzugefügt, die für zukünftige Ermittler hilfreich sein könnten, ohne sich eingehend mit Kommentaren zu befassen.

Antwort 1 :

Sie versuchen, einen Dialog anzuzeigen, nachdem Sie eine Aktivität beendet haben.

Antwort 2

Dieser Fehler kann unter bestimmten Umständen etwas irreführend sein (obwohl die Antwort immer noch völlig korrekt ist) - dh in meinem Fall wurde eine nicht behandelte Ausnahme in eine AsyncTask ausgelöst, wodurch die Aktivität heruntergefahren wurde, und ein offener Fortschrittsdialog verursachte diese Ausnahme Die "echte" Ausnahme war etwas früher im Protokoll

Antwort 3

Rufen Sie Entlassung () für die Dialoginstanz auf, die Sie vor dem Beenden Ihrer Aktivität erstellt haben, z. B. in onPause () oder onDestroy ().


2
@Override public void onStop () {if (dialog! = Null) {dialog.dismiss (); dialog = null; }}
Md.Tarikul Islam

14
Auch nach 8 Jahren ist dies noch relevant! Ich habe die Ausnahme erhalten, weil die Aktivität geschlossen wurde, während versucht wurde, meinen AlertDialog anzuzeigen (also Antwort 2). Am Ende fand ich heraus, dass die App der Szene ein "Null" -Objekt hinzufügte (hätte nicht passieren sollen, aber es geschah), aber es gab keine zusätzliche Ausnahme dafür und das Ganze wurde durch das "Durchsickern" maskiert Fenster "Ausnahme stattdessen.
Neph

Ist es möglich, nach allen geöffneten Dialogen zu suchen und diese in onStop () zu schließen? Ich generiere Dialoge in einer ListView, wenn ich auf Elemente klicke. Ich bin nicht sicher, wie ich ihre Referenz vom onStop abrufen soll.
Myoch

1
Antwort 3 ist die beste Lösung. hat sehr für mich gearbeitet. Danke kaze, Alex !!
Amit Bansode

Zusätzlicher Tipp, wenn Sie den Dialog in einer Schleife anzeigen, stellen Sie sicher, dass die Schleife nach Beendigung der Aktivität beendet wird
Thecarisma

406

Die Lösung besteht darin, dismiss()das von DialogIhnen erstellte aufzurufen, viewP.java:183bevor Sie das verlassen Activity, z onPause(). Alle Windows & Dialogs sollten vor dem Verlassen eines geschlossen werden Activity.


3
Wenn der Benutzer das Telefon dreht, sollten alle Dialoge geschlossen werden. Das klingt nicht richtig.
LarsH

@LarsH Wie Sie sehen können, wurde meine Antwort vor mehr als 7 Jahren geschrieben, und dies war zu dieser Zeit definitiv wahr. Ich arbeite nicht mehr mit Android, aber basierend auf dem, was ich in der Dokumentation sehe , ist dies möglicherweise immer noch der Fall, aber Android hat seitdem einen langen Weg zurückgelegt (Fragmente eingeführt, um nur einen zu nennen), sodass es jetzt wahrscheinlich einfacher ist.
Molnarm

108

Wenn Sie verwenden AsyncTask, kann diese Protokollnachricht wahrscheinlich irreführend sein. Wenn Sie in Ihrem Protokoll nachschlagen, finden Sie möglicherweise einen weiteren Fehler, wahrscheinlich einen in Ihrer doInBackground()Methode, der dazu führt AsyncTask, dass Ihr Strom Activityexplodiert, und wenn der AsyncTaskzurückkommt, kennen Sie den Rest. Einige andere Benutzer haben das hier bereits erklärt :-)


22
In diesem Fall kann ich manchmal die eigentliche Ausnahme nicht erkennen. Um die eigentliche Ausnahme zu finden, kommentieren Sie einfach die Datei progressDialog.show () aus und führen Sie die App erneut aus. Jetzt sehen Sie sie.
Stuck

Hallo Leute! Wie oben von @Stuck erwähnt, kann ich auch die wahre Ausnahme nicht sehen. Was ich getan habe? Ich habe es anhand von Bruchstellen verfolgt und festgestellt, dass ich eine Referenz einer Anwendungsklasse innerhalb der Methode doInBackgroundder AsyncTaskKlasse verwendet habe, ohne sie jedoch in der AndroidManifestDatei mit der folgenden Eigenschaft zu deklarieren android:name: android:name="my.package.MyApplicationClass". Wenn Sie es verwenden, sollten AsyncTaskSie immer daran denken, Ihre Warnung innerhalb der Methode zu instanziieren onPreExecuteund sie zu schließen onPostExecute.
GFPF

66

Ich habe diesen Fehler ausgelöst, indem ich versehentlich hide()statt dismiss()auf einen aufgerufen habe AlertDialog.


4
Genau das, was mir passiert ist. Das Aufrufen von hide () und das anschließende Setzen des Dialogfelds auf null ist ebenfalls keine gültige Alternative.
Lucas Tulio

Ich würde das Problem dahinter wirklich kennen. Aber entlassen () hat mir geholfen!
Karoly

59

Sie können diese Ausnahme nur durch einen einfachen / dummen Fehler erhalten, indem Sie (zum Beispiel) versehentlich anrufen, finish()nachdem Sie eine angezeigt haben AlertDialog, wenn Sie eine break call-Anweisung in einer switch-Anweisung verpassen ...

   @Override
   public void onClick(View v) {
    switch (v.getId()) {
        case R.id.new_button:
            openMyAlertDialog();
            break; <-- If you forget this the finish() method below 
                       will be called while the dialog is showing!
        case R.id.exit_button:
            finish();
            break;
        }
    }

Die finish()Methode schließt das Activity, aber das AlertDialogwird immer noch angezeigt!

Wenn Sie also aufmerksam auf den Code starren, nach schlechten Threading-Problemen oder komplexer Codierung suchen, verlieren Sie den Wald vor lauter Bäumen nicht aus den Augen. Manchmal kann es einfach und dumm sein wie eine fehlende break-Anweisung. :) :)


Mehr oder weniger genau mein Problem. Wird nach dem Erstellen des Dialogfelds in onError als beendet bezeichnet, nicht in onClick für die Schaltfläche zum Schließen.
jbass

46

Die Antworten auf diese Frage waren alle richtig, aber ein wenig verwirrend für mich, um tatsächlich zu verstehen, warum. Nachdem ich ungefähr 2 Stunden herumgespielt hatte, traf mich der Grund für diesen Fehler (in meinem Fall):

Durch das Lesen anderer Antworten wissen Sie bereits, dass der X has leaked window DecorView@d9e6131[]Fehler bedeutet , dass beim Schließen Ihrer App ein Dialogfeld geöffnet war. Aber warum?

Es kann sein, dass Ihre App aus einem anderen Grund abgestürzt ist, während Ihr Dialog geöffnet war

Dies führte dazu, dass Ihre App aufgrund eines Fehlers in Ihrem Code geschlossen wurde, was dazu führte, dass der Dialog gleichzeitig mit dem Schließen Ihrer App aufgrund des anderen Fehlers geöffnet blieb.

Schauen Sie sich also Ihre Logik an. Lösen Sie den ersten Fehler, und der zweite Fehler löst sich von selbstGeben Sie hier die Bildbeschreibung ein

Ein Fehler verursacht einen anderen, der einen anderen verursacht, wie DOMINOS!


2
Ich kann nicht glauben, dass dies nur eine positive Bewertung hat. Oder wir sind einfach sehr schlecht im Programmieren. Hahaha, mir hat auch Ihre Domino-Analogie gefallen
user2161301

Lösen Sie den ersten Fehler und der zweite Fehler tritt nicht auf . Diese Analogie hat mir geholfen.
Itabdullah

Dies ist nicht ganz richtig. Instanzen wie die Telefonrotation können auch dazu führen, dass eine "Aktivitätsrotation" stattfindet.
Sreekanth Karumanaghat

36

Dieses Problem tritt auf, wenn Sie versuchen, einen Dialog anzuzeigen, nachdem Sie eine Aktivität beendet haben.

Ich habe dieses Problem nur gelöst, indem ich den folgenden Code aufgeschrieben habe:

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

Grundsätzlich sollten Sie in welcher Klasse Sie progressDialog gestartet haben, die onDestroy-Methode überschreiben und auf diese Weise vorgehen. Es wurde das Problem "Aktivität hat Fenster durchgesickert" gelöst.


Es wird nicht garantiert, dass onDestroy aufgerufen wird. Besser, diesen Code in onPause oder onStop
Amruta-Pani

19

Ich hatte vor kurzem das gleiche Problem.

Der Grund für dieses Problem ist, dass die Aktivität geschlossen wird, bevor der Dialog beendet wird. Es gibt verschiedene Gründe dafür. Die in den obigen Beiträgen genannten sind ebenfalls korrekt.

Ich bin in eine Situation geraten, weil ich im Thread eine Funktion aufgerufen habe, die eine Ausnahme auslöste. Aufgrund dessen wurde das Fenster geschlossen und damit die Ausnahme.


16

Schließen Sie den Dialog, wenn die Aktivität zerstört wird

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

Wenn pDialog null ist, wird dies einen Fehler auslösen, wenn Sie den Status des Null-Dialogs abfragen
Jonathan Dunn

1
nein, es wird nicht @JonDunn, weil Java den zweiten Booleschen Wert nicht verarbeitet, wenn der erste falsch ist
matdev

13

Das könnte helfen.

if (! isFinishing()) {

    dialog.show();

    }

2
Unter Hunderten ähnlicher Antworten gibt es niemanden, der zeigt, wie man überprüft, ob Fenster vorhanden sind. Sie sparen mir also etwas Zeit, um den Weg dazu zu finden. Vielen Dank.
kolyaseg

11

Ich hatte die gleiche obskure Fehlermeldung und hatte keine Ahnung warum. Angesichts der Hinweise aus den vorherigen Antworten habe ich meine Nicht-GUI-Aufrufe in mDialog.finish () in mDialog.dismiss () geändert, und die Fehler sind verschwunden. Dies hatte keinen Einfluss auf das Verhalten meines Widgets, war jedoch beunruhigend und hätte einen wichtigen Speicherverlust anzeigen können.


Es wurde bemerkt, dass ich vor dem Aufruf von finish () einen mDialog.hide () ausführte. Das Ändern in mDialog.dismiss () hat den Trick getan.
Mai

11

Ich habe diese Protokolle in meiner Video-Player-Anwendung erhalten. Diese Nachrichten wurden ausgelöst, während der Videoplayer geschlossen war. Interessanterweise habe ich diese Protokolle einmal in einigen Läufen auf zufällige Weise abgerufen. Auch meine Bewerbung beinhaltet keine progressdialog. Schließlich habe ich dieses Problem mit der folgenden Implementierung umgangen.

@Override
protected void onPause()
{
    Log.v("MediaVideo", "onPause");
    super.onPause();
    this.mVideoView.pause();
    this.mVideoView.setVisibility(View.GONE);
}

@Override
protected void onDestroy()
{
    Log.v("MediaVideo", "onDestroy");
    super.onDestroy();
}

@Override
protected void onResume()
{
    Log.v("MediaVideo", "onResume");
    super.onResume();
    this.mVideoView.resume();
}

Überschreiben Sie das OnPausewith call to mVideoView.pause()und das set visibilityto GONE. Auf diese Weise konnte ich das " Activity has leaked window" Protokollfehlerproblem beheben .


Ich stehe auch vor dem gleichen Problem. Ich habe diese Codezeilen in meinen Code eingefügt, aber es hat nicht funktioniert und gibt den gleichen Fehler "android.view.WindowLeaked, der ursprünglich hinzugefügt wurde" und auch nicht das Video abspielen und gibt "Video kann nicht abgespielt werden"
User42590

10

Ich hatte das gleiche Problem und fand diese Seite. Während meine Situation anders war, rief ich finishvon einem ifBlock aus an, bevor er die Warnbox definierte.

Einfach anzurufen dismisswürde also nicht funktionieren (da es noch nicht gemacht wurde), aber nachdem ich Alex Volovoys Antwort gelesen und erkannt hatte, dass es die Alarmbox war , die es verursachte. Ich habe versucht, direkt nach dem Ende in diesem ifBlock eine return-Anweisung hinzuzufügen , wodurch das Problem behoben wurde.

Ich dachte, als du fertig angerufen hast, hat es alles gestoppt und ist genau dort fertig geworden, aber das tut es nicht. Es scheint bis zum Ende des Codeblocks zu gehen, in dem es sich befindet, und endet dann.

Wenn Sie also eine Situation implementieren möchten, in der es manchmal vor dem Ausführen von Code beendet wird, müssen Sie direkt nach dem Ende eine return-Anweisung einfügen, oder es geht weiter und verhält sich so, als ob das Ende am Ende des Codes aufgerufen wurde Codeblock nicht dort, wo Sie ihn genannt haben. Deshalb habe ich all diese seltsamen Fehler bekommen.

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();
}

Wenn Sie die Rückgabe nicht direkt nach dem Aufruf von finish dort einfügen, verhält es sich so, als hätten Sie sie nach dem aufgerufen, alert.show();und daher würde das Fenster durch Beenden durchgesickert, sobald Sie den Dialog angezeigt haben, obwohl dies der Fall ist nicht der Fall, denke es immer noch.

Ich dachte, ich würde dies wie hier hinzufügen, da dies zeigt, dass der Zielbefehl anders funktioniert als ich dachte, und ich würde vermuten, dass es andere Leute gibt, die genauso denken wie ich, bevor ich dies entdeckte.


7

Dies ist nicht die Antwort auf die Frage, aber sie ist für das Thema relevant.

Wenn die Aktivität ein Attribut im Manifest definiert hat

 android:noHistory="true"

Nach der Ausführung von onPause () geht der Aktivitätskontext verloren. Alle Ansichten, die diesen Kontext verwenden, geben möglicherweise diesen Fehler aus.


Können Sie etwas Ähnliches für progessdialog.show().. und progressdialog.hide()in asynctaskder gleichen Aktivität anstelle von onPause()ab erzählen activity? Schauen Sie sich mein Problem an ... stackoverflow.com/questions/39332880/…
Bhuro

1
es funktioniert perfekt für mich: android: noHistory = "true"
Shohel Rana

6

Versuchen Sie nicht nur, eine Warnung anzuzeigen, sondern sie kann auch aufgerufen werden, wenn Sie eine bestimmte Instanz einer Aktivität beenden und versuchen, eine neue Aktivität / einen neuen Dienst zu starten oder zu stoppen.

Beispiel:

OldActivity instance;

    oncreate() {
       instance=this;
    }
    instance.finish();
    instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));

6

Im Allgemeinen tritt dieses Problem aufgrund des Fortschrittsdialogs auf: Sie können dieses Problem mithilfe einer der folgenden Methoden in Ihrer Aktivität lösen:

 // 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();
                }
            }

5

Hatte das Problem, wo ich eine Aktivität beendet habe, als noch ein ProgressDialog angezeigt wurde.

Blenden Sie also zuerst den Dialog aus und beenden Sie dann die Aktivität.


5

Versuchen Sie diesen Code:

public class Sample extends Activity(){
@Override
 public void onCreate(Bundle instance){

}
 @Override
    public void onStop() {
        super.onStop();
      progressdialog.dismiss(); // try this
    }

}

progressdialog.dismiss();Dadurch kann eine NullPointerException erstellt werden.
tpk

5

Dies kann der Fall sein, wenn Sie einen doInBackground()Funktionsfehler haben und diesen Code haben.

Versuchen Sie endlich, einen Dialog hinzuzufügen. Überprüfen und beheben Sie zunächst die doInBackground()Funktion

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();

5

Dies geschah zu mir , wenn ich verwende ProgressDialogin AsyncTask. Eigentlich benutze ich hide()Methode in onPostExecute. Auf der Grundlage der Antwort von @ Alex Volovoy Ich brauche die Verwendung dismiss()mit ProgressDialogihm in OnPostExecute und ihre getan zu entfernen.

progressDialog.hide(); // Don't use it, it gives error

progressDialog.dismiss(); // Use it

Dies ist nicht wirklich die vollständige Antwort. Es gibt zwei Möglichkeiten, einen Dialog zu verlieren. 1) Wenn Sie ein haben AsyncTaskund das zeigen Dialog, passiert etwas, das den ActivityAufruf onPause()ausführt (möglicherweise eine Logik in Ihrer AsyncTask selbst, wie ein Listener, dann wird es auslaufen. 2) Wie oben erwähnt, ist das, Dialogwas damit erstellt wurde, Activity Contextniemals entlassen und Activitygeht weiter.
Tricknologie

5

Der Activity has leaked window that was originally added...Fehler " " tritt auf, wenn Sie versuchen, eine Warnung anzuzeigen, nachdem die Activityeffektiv istfinished .

Sie haben zwei Möglichkeiten AFAIK:

  1. Überdenken Sie die Anmeldung Ihrer Warnung: Rufen Sie an dismiss() die andialog bevor Sie Ihre Aktivität tatsächlich beenden.
  2. Setzen Sie das dialogin einen anderen Thread und führen Sie es darauf aus thread(unabhängig vom aktuellen activity).

5

Hier ist eine Lösung, wenn Sie AlertDialog schließen möchten, aber keinen Verweis darauf in der Aktivität behalten möchten .

Lösung erfordert, dass Sie androidx.lifecycle haben Abhängigkeit in Ihrem Projekt haben (ich glaube, im Moment des Kommentars ist es eine häufige Anforderung)

Auf diese Weise können Sie die Entlassung von Dialogen an ein externes Objekt (Beobachter) delegieren, und Sie müssen sich nicht mehr darum kümmern, da sie sich automatisch abmeldet, wenn die Aktivität endet. (Hier ist der Beweis: https://github.com/googlecodelabs/android-lifecycles/issues/5 ).

Der Beobachter behält also den Bezug zum Dialog und die Aktivität den Bezug zum Beobachter. Wenn "onPause" passiert - der Beobachter schließt den Dialog und wenn "onDestroy" passiert - entfernt die Aktivität den Beobachter, so dass kein Leck auftritt (zumindest sehe ich keinen Fehler mehr in logcat).

// observer
class DialogDismissLifecycleObserver( private var dialog: AlertDialog? ) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        dialog?.dismiss()
        dialog = null
    }
}
// activity code
private fun showDialog() {
        if( isDestroyed || isFinishing ) return
        val dialog = AlertDialog
            .Builder(this, R.style.DialogTheme)
            // dialog setup skipped
            .create()
        lifecycle.addObserver( DialogDismissLifecycleObserver( dialog ) )
        dialog.show()
}

4

Fenster durchgesickerte Ausnahmen haben zwei Gründe:

1) Anzeigen des Dialogfelds, wenn kein Aktivitätskontext vorhanden ist. Um dies zu lösen, sollten Sie das Dialogfeld nur anzeigen, wenn Sie sicher sind, dass Aktivität vorhanden ist:

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

2) Schließen Sie den Dialog nicht angemessen, um diesen Code zu lösen:

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

4

Sie müssen ProgressdialogObjekt in onPreExecuteMethode von machen AsyncTaskund Sie sollten dismisses auf onPostExecuteMethode.


4

Die beste Lösung besteht darin, im Dialogfeld "Versuch abzufangen und zu schließen" einen Dialog hinzuzufügen, wenn eine Ausnahme auftritt

Verwenden Sie einfach den folgenden Code

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

3
Ist der Dialog nicht null, nachdem er als beendet bezeichnet wurde? Ich denke, er dialog.dismiss()wird auch Fehler verursachen
Ashu Kumar

3

In meinem Fall war der Grund, dass ich vergessen habe, eine Berechtigung in die Android-Manifestdatei aufzunehmen.

Wie habe ich es herausgefunden? Nun, genau wie @Bobby in einem Kommentar unter der akzeptierten Antwort sagt, scrollen Sie einfach weiter nach oben zu Ihren Protokollen und Sie werden den ersten Grund oder das erste Ereignis sehen, das die Ausnahme wirklich ausgelöst hat. Anscheinend ist die Meldung "Aktivität hat Fenster durchgesickert, das ursprünglich hinzugefügt wurde" nur eine Ausnahme, die sich aus der ersten Ausnahme ergibt.


3

Versuchen Sie es mit dem folgenden Code. Es funktioniert jedes Mal, wenn Sie den Fortschrittsdialog schließen und sehen, ob seine Instanz verfügbar ist oder nicht.

try {
        if (null != progressDialog && progressDialog.isShowing()) {
            progressDialog.dismiss();
            progressDialog = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

2

Die beste Lösung ist dies vor dem Anzeigen von progressbaroderprogressDialog

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

  //Show Your Progress Dialog

}

Das funktioniert bei mir nicht. Ich habe Dialog.show () nach der Antwort vom HTTP-Aufruf und wenn ich in der Zwischenzeit den Bildschirm drehe, wird die Aktivität getrennt, aber es scheint, dass isShown == true vor Dialog.show () ist, und dann stürzt Dialog trotz dieser Überprüfung ab
Michał Ziobro

1

Stellen Sie einfach sicher, dass Ihre Aktivität nicht unerwartet aufgrund einiger Ausnahmen in Ihrem Code geschlossen wird. Im Allgemeinen tritt dies bei asynchronen Aufgaben auf, wenn die Aktivität in der doinBackground-Methode erzwungen wird und die asynctask dann zur onPostexecute-Methode zurückkehrt.


1

Ich habe eine andere Lösung dafür und würde gerne wissen, ob sie Ihnen gültig erscheint: Anstatt in onDestroy, das die führende Lösung zu sein scheint, zu verwerfen, erweitere ich ProgressDialog ...

public class MyProgressDialog extends ProgressDialog {

  private boolean isDismissed;

  public MyProgressDialog(Context context) {
    super(context);
  }

  @Override
  public void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    dismiss();
  }

  @Override
  public void dismiss() {
    if (isDismissed) {
      return;
    }
    try {
      super.dismiss();
    } catch (IllegalArgumentException e) {
      // ignore
    }
    isDismissed = true;
  }

Dies ist vorzuziehen, AFAIC, da Sie den Fortschrittsdialog nicht als Mitglied halten müssen, sondern nur feuern (anzeigen) und vergessen müssen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.