1305 Stimmen

Die Aktivität hat das Fenster geleakt, das ursprünglich hinzugefügt wurde.

Was ist dieser Fehler und warum tritt er auf?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP hat das Fenster com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 ausgelaufen, das ursprünglich hier hinzugefügt wurde
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP hat das Fenster com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 ausgelaufen, das ursprünglich hier hinzugefügt wurde
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.view.ViewRoot.(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850):     bei dalvik.system.NativeStart.main(Native Method)

12voto

Kit Ramos Punkte 1301

Ich hatte das gleiche Problem und fand diese Seite, und obwohl meine Situation anders war, rief ich finish aus einem if Block auf, bevor das Alertfeld definiert wurde.

Also würde einfach dismiss Aufrufen nicht funktionieren (da es noch nicht erstellt wurde), aber nachdem ich die Antwort von Alex Volovoy gelesen hatte und realisierte, dass es das Alertfeld war, das es verursachte. Ich versuchte, unmittelbar nach dem finish innerhalb dieses if Blocks eine return-Anweisung hinzuzufügen und das behob das Problem.

Ich dachte, sobald man finish aufruft, würde alles gestoppt und endet genau an dieser Stelle, aber das tut es nicht. Es scheint bis zum Ende des Blockes des Codes zu gehen, in dem es sich befindet, und dann zu beenden.

Also, wenn Sie eine Situation implementieren möchten, in der es manchmal vor der Ausführung eines Codes endet, müssen Sie unbedingt eine return-Anweisung genau nach dem finish hinzufügen, sonst wird es weitermachen und so tun, als ob finish am Ende des Code-Blocks aufgerufen wurde und nicht dort, wo Sie es aufgerufen haben. Deshalb bekam ich all diese seltsamen Fehlermeldungen.

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("Frage")
        .setMessage("Möchten Sie diese Datei öffnen?"+aDirectory.getName());
    alert
        .setPositiveButton("OK", okButtonListener)
        .setNegativeButton("Abbrechen", cancelButtonListener);
    alert.show();
}

Wenn Sie das return nicht direkt nach dem Aufruf von finish dort platziert haben, wird es so wirken, als hätten Sie es nach dem alert.show(); aufgerufen und daher würde es sagen, dass das Fenster durch das Beenden kurz nach dem Erscheinen des Dialogfelds undicht ist, auch wenn das nicht der Fall ist.

Ich dachte, ich füge das hier hinzu, da dies zeigt, dass der finish-Befehl anders reagierte, als ich dachte, und ich vermute, dass es andere gibt, die dasselbe dachten wie ich, bevor ich dies entdeckte.

12voto

Melinda Green Punkte 2030

Ich hatte die gleiche obskure Fehlermeldung und hatte keine Ahnung, warum. Aufgrund von Hinweisen aus den vorherigen Antworten habe ich meine Nicht-GUI-Aufrufe von mDialog.finish() in mDialog.dismiss() geändert und die Fehler verschwanden. Das hatte zwar keinen Einfluss auf das Verhalten meines Widgets, war jedoch beunruhigend und könnte durchaus auf ein wichtiges Memory-Leak hinweisen.

12voto

dmz9 Punkte 123

Hier ist eine Lösung, wenn Sie AlertDialog ablehnen möchten, aber keine Referenz behalten möchten darin innerhalb der Aktivität.

die Lösung erfordert, dass Sie die Abhängigkeit von androidx.lifecycle in Ihrem Projekt haben (ich glaube, dass es zum Zeitpunkt des Kommentars eine gängige Anforderung ist).

dies ermöglicht es Ihnen, das Schließen des Dialogfelds an ein externes Objekt (Beobachter) zu delegieren, und Sie müssen sich nicht mehr darum kümmern, da es automatisch abgemeldet wird, wenn die Aktivität beendet wird. (hier ist der Beweis: https://github.com/googlecodelabs/android-lifecycles/issues/5).

Der Beobachter behält also die Referenz zum Dialogfeld, und die Aktivität behält die Referenz zum Beobachter. Wenn "onPause" passiert - der Beobachter schließt das Dialogfeld, und wenn "onDestroy" passiert - die Aktivität entfernt den Beobachter, damit kein Leak passiert (nun, zumindest sehe ich keinen Fehler mehr im Logcat)

// Beobachter
class DialogDismissLifecycleObserver( private var dialog: AlertDialog? ) : LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        dialog?.dismiss()
        dialog = null
    }
}
// Aktivitätscode
private fun showDialog() {
        if( isDestroyed || isFinishing ) return
        val dialog = AlertDialog
            .Builder(this, R.style.DialogTheme)
            // Dialog Einrichtung übersprungen
            .create()
        lifecycle.addObserver( DialogDismissLifecycleObserver( dialog ) )
        dialog.show()
}

12voto

InvisiblePoint Punkte 139

Ich habe diese Logs in meiner Video-Player-Anwendung erhalten. Diese Nachrichten wurden geworfen, während der Video-Player geschlossen war. Interessanterweise habe ich diese Logs in unregelmäßigen Abständen einmal in ein paar Durchläufen bekommen. Außerdem ist meine Anwendung nicht an einem progressdialog beteiligt. Schließlich konnte ich das Problem mit der folgenden Implementierung lösen.

@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 OnPause mit dem Aufruf von mVideoView.pause() und setzen Sie die Sichtbarkeit auf GONE. Auf diese Weise konnte ich das "Activity has leaked window" Log-Fehlerproblem lösen.

10voto

Bapusaheb Shinde Punkte 751

Im Allgemeinen tritt dieses Problem aufgrund des Fortschrittsdialogs auf: Sie können dies lösen, indem Sie eine der folgenden Methoden in Ihrer Aktivität verwenden:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X