web-dev-qa-db-fra.com

La fenêtre d'activité a fuité - Android

Regardez ces morceaux de code:

Vues personnalisées et attributs de fenêtre sur Android

Problème

Lorsque je clique sur le bouton "Accueil", exception est lancé: Activity a une fuite de fenêtre ... à partir de cette ligne:

localWindowManager.addView(colourView, layoutParams);

Question (s)

Savez-vous ce qui peut en être la cause?

Le problème ne se produit pas lorsque je ferme l'application avec le bouton de retour.

Journaux d'exception/d'erreur

W/InputManagerService(   96): Starting input on non-focused client com.Android.internal.view.IInputMethodClient$Stub$Proxy@40908148 (uid=10056 pid=1368)
D/CordovaActivity( 1368): CordovaActivity.onDestroy()
D/CordovaWebView( 1368): >>> loadUrlNow()
E/WindowManager( 1368): Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368): Android.view.WindowLeaked: Activity com.phonegap.helloworld.HelloWorld has leaked window pl.edu.uj.tcs.student.xxx.Display$Layer@40589368 that was originally added here
E/WindowManager( 1368):         at Android.view.ViewRoot.<init>(ViewRoot.Java:258)
E/WindowManager( 1368):         at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:148)
E/WindowManager( 1368):         at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:91)
E/WindowManager( 1368):         at Android.view.Window$LocalWindowManager.addView(Window.Java:424)
E/WindowManager( 1368):         at pl.edu.uj.tcs.student.xxx.Display.setColorsViews(Display.Java:181)
E/WindowManager( 1368):         at pl.edu.uj.tcs.student.xxx.Display$3.run(Display.Java:139)
E/WindowManager( 1368):         at Android.os.Handler.handleCallback(Handler.Java:587)
E/WindowManager( 1368):         at Android.os.Handler.dispatchMessage(Handler.Java:92)
E/WindowManager( 1368):         at Android.os.Looper.loop(Looper.Java:130)
E/WindowManager( 1368):         at Android.app.ActivityThread.main(ActivityThread.Java:3683)
E/WindowManager( 1368):         at Java.lang.reflect.Method.invokeNative(NativeMethod)
E/WindowManager( 1368):         at Java.lang.reflect.Method.invoke(Method.Java:507)
E/WindowManager( 1368):         at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:839)
E/WindowManager( 1368):         at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:597)
E/WindowManager( 1368):         at dalvik.system.NativeStart.main(Native Method)

D/CordovaActivity( 1368): onMessage(onPageStarted,about:blank)
D/CordovaWebViewClient( 1368): onPageFinished(about:blank)
D/CordovaActivity( 1368): onMessage(onPageFinished,about:blank)
D/CordovaActivity( 1368): onMessage(exit,null)
I/power   (   96): *** set_screen_state 0

MODIFIER:

Comment puis-je ajouter quelque chose aux fonctions onPause (), onStop () etc. dans Cordova Activity?

EDIT 2:

Pourquoi c'est un problème? Parce que tout ce que je crée est une classe qui étend CordovaPlugin et de petites classes auxiliaires. C'est tout. Je ne suis pas en mesure (je suppose) de modifier le corps de la classe d'activité. Tout ce que je peux faire, c'est y faire référence en appelant la fonction cordova.getActivity().

25
tomwesolowski

Qu'est-ce qu'une fuite dans la programmation?

La mémoire que vous acquérez et ne libérez pas conduit à une fuite de mémoire. Il en va de même avec les (fenêtres/boîtes de dialogue).

Que se passe-t-il ici?

Vous essayez d'ajouter une fenêtre et pendant qu'elle apparaît, elle est au premier plan, mais lorsque vous appuyez sur le bouton d'accueil, elle est interrompue puis arrêtée (essayez de porter un toast dans onStop () et onPause ()).

Puisque vous n'avez pas dit au système de supprimer votre vue, elle reste donc attachée à la fenêtre qui a maintenant disparu/détachée de l'application. Par conséquent, selon le système, votre customView occupait l'espace qu'elle n'avait pas libéré.

Solution

Dans votre onStop() or onPause() etonDestroy() assurez-vous de fermer votre vue (dismiss() s'il s'agit d'une boîte de dialogue) ou de la supprimer (remove() si ajoutée à l'aide du gestionnaire de fenêtres) .

Ajoutez les fonctions de fermeture ou de suppression à l'intérieur de votre fonction de déchargement car vous avez mentionné qu'en appuyant sur le bouton de retour, vous obtenez cette erreur. En quittant une application, sa méthode onUnload() est appelée.

Suggestion (ignorer si pas dans le contexte)

Comme je peux le constater, vous essayez de créer une fenêtre d'alerte système qui passe par-dessus tout ce qui se trouve en dessous. L'ajout de ce type de fenêtres contextuelles dans l'activité est risqué car il peut provoquer des problèmes de fuite. Vous pouvez en fait ajouter ce type de fenêtre via un Service afin qu'il survit à votre activité et apparaisse partout sur l'appareil (si c'est ce dont vous avez besoin).

Vérifiez cela

Mise à jour 2-Le cycle de vie de Cordova

Pourquoi n'essayez-vous pas de remplacer la méthode onUnload dans votre classe CordovaPlugin.J'ai essayé de trouver, mais les docs mentionnent l'existence des méthodes onPause et onResume.Si vous avez onUnload dans la classe CordovaPlugin, puis supprimez la vue vous faites dans votre méthode runOnUiThread de classe d'affichage.

47
cafebabe1991

Vous essayez d'afficher un Dialog après avoir quitté une activité.

La solution consiste à appeler dismiss() sur le Dialog que vous avez créé avant de quitter le Activity, par ex. dans onPause (). Toutes les fenêtres et boîtes de dialogue doivent être fermées avant de quitter un Activity.

@Override
 protected void onStop() {
  super.onStop();
  if (loadingDlg != null) {
   loadingDlg.dismiss();
   loadingDlg = null;
  }
}

J'espère que cela devrait vous être utile.

Activity-has-leaked-window-that-was-original-added

11
Jebasuthan

Vérifiez la météo que la boîte de dialogue affiche ou non

@Override
  protected void onStop() {
    super.onStop();
if (loadingDlg != null) {

        if(loadingDlg.isShowing())
        loadingDlg.dismiss();

        loadingDlg = null;
 }
}
2
Karthick pop

Une fenêtre qui fuit se produit généralement lorsque votre contexte affiche des boîtes de dialogue et que ce contexte est soudainement forcé de fermer que votre boîte de dialogue n'a pas été fermée correctement.

Pour résoudre ce problème, vous devez corriger vos erreurs avant que la fenêtre ne présente une fuite.

0
Rick Royd Aban

J'ai eu un finish () qui a été appelé place avant l'appel de mon AlertDialog, ce qui a provoqué la fin de l'activité avant l'appel de AlertDialog. J'ai supprimé la finition () et l'ai mise une fois que l'utilisateur a terminé sa saisie à l'aide du AlertDialog et que la fuite de la fenêtre a été corrigée.

0
JanB