Quelle est cette erreur et pourquoi se produit-elle?
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)
android
memory-leaks
dialog
Pentium10
la source
la source
Réponses:
Vous essayez d'afficher une boîte de dialogue après avoir quitté une activité.
[ÉDITER]
Cette question est l'une des principales recherches sur Google pour les développeurs Android, ajoutant donc quelques points importants des commentaires, ce qui pourrait être plus utile pour le futur enquêteur sans entrer dans la profondeur de la conversation.
Réponse 1 :
Réponse 2
Réponse 3
la source
La solution est d'appeler
dismiss()
le queDialog
vous avez créé dansviewP.java:183
avant de quitter leActivity
, par exemple dansonPause()
. TousWindow
lesDialog
articles doivent être fermés avant de quitter unActivity
.la source
Si vous utilisez
AsyncTask
, probablement ce message de journal peut être trompeur. Si vous recherchez dans votre journal, vous pourriez trouver une autre erreur, probablement une dans votredoInBackground()
méthodeAsyncTask
, qui faitActivity
exploser votre courant , et donc une fois que leAsyncTask
retour est fait ... eh bien, vous connaissez le reste. D'autres utilisateurs l'ont déjà expliqué ici :-)la source
doInBackground
de laAsyncTask
classe , mais sans la déclarer dans leAndroidManifest
fichier en utilisant la propriétéandroid:name
comme ceci:android:name="my.package.MyApplicationClass"
. Une bonne pratique lors de son utilisationAsyncTask
est de toujours penser à instancier votre alerte dans la méthodeonPreExecute
et à la désactiveronPostExecute
.J'ai déclenché cette erreur en appelant par erreur
hide()
plutôt quedismiss()
sur unAlertDialog
.la source
Vous pouvez obtenir cette exception simplement par une erreur simple / stupide, en appelant (par exemple) accidentellement
finish()
après avoir affiché unAlertDialog
, si vous manquez une instruction break break dans une instruction switch ...La
finish()
méthode fermera leActivity
, mais leAlertDialog
s'affiche toujours!Ainsi, lorsque vous regardez attentivement le code, à la recherche de problèmes de threads incorrects ou de codage complexe et autres, ne perdez pas de vue la forêt pour les arbres. Parfois, cela peut être quelque chose d'aussi simple et stupide qu'une déclaration de rupture manquante. :)
la source
Les réponses à cette question étaient toutes correctes, mais un peu déroutantes pour moi de réellement comprendre pourquoi. Après avoir joué pendant environ 2 heures, la raison de cette erreur (dans mon cas) m'a frappé:
Vous savez déjà, en lisant d'autres réponses, que l'
X has leaked window DecorView@d9e6131[]
erreur a signifie qu'une boîte de dialogue était ouverte lorsque votre application a fermé. Mais pourquoi?Il se peut que votre application se soit bloquée pour une autre raison alors que votre boîte de dialogue était ouverte.
Cela a conduit à la fermeture de votre application en raison d'un bogue dans votre code, ce qui a entraîné la fermeture de la boîte de dialogue en même temps que votre application en raison de l'autre erreur.
Alors, regardez à travers votre logique. Résolvez la première erreur, puis la deuxième erreur se résoudra d'elle-même
Une erreur en provoque une autre, qui en provoque une autre, comme DOMINOS!
la source
Ce problème se produit lorsque vous essayez d'afficher une boîte de dialogue après avoir quitté une activité.
Je viens de résoudre ce problème en écrivant simplement le code suivant:
Fondamentalement, à partir de quelle classe vous avez commencé progressDialog, remplacez la méthode onDestroy et procédez de cette façon. Il a résolu le problème «L'activité a une fuite de fenêtre».
la source
J'ai récemment rencontré le même problème.
La raison de ce problème est que l'activité est fermée avant la fermeture de la boîte de dialogue. Il y a plusieurs raisons à cela. Ceux mentionnés dans les articles ci-dessus sont également corrects.
Je suis entré dans une situation, car dans le fil, j'appelais une fonction qui lançait une exception. À cause de quoi la fenêtre était fermée et donc l'exception.
la source
Fermer la boîte de dialogue lorsque l'activité détruit
la source
Cela pourrait aider.
la source
J'ai eu le même message d'erreur obscur et je ne savais pas pourquoi. Compte tenu des indices des réponses précédentes, j'ai changé mes appels non-GUI en mDialog.finish () pour être mDialog.dismiss () et les erreurs ont disparu. Cela n'affectait pas le comportement de mon widget, mais c'était déconcertant et aurait bien pu signaler une fuite de mémoire importante.
la source
J'obtenais ces journaux dans mon application de lecteur vidéo. Ces messages ont été lancés alors que le lecteur vidéo était fermé. Fait intéressant, j'avais l'habitude d'obtenir ces journaux une fois en quelques exécutions de manière aléatoire. De plus, ma candidature ne concerne aucun
progressdialog
. Enfin, j'ai contourné ce problème avec l'implémentation ci-dessous.Remplacez le
OnPause
avec appel àmVideoView.pause()
et l'ensemblevisibility
àGONE
. De cette façon, je pourrais résoudre le problème "Activity has leaked window
" d'erreur de journal.la source
J'avais le même problème et j'ai trouvé cette page, et bien que ma situation soit différente, j'ai appelé à
finish
partir d'unif
bloc avant qu'il ne définisse la boîte d'alerte.Donc, simplement appeler
dismiss
ne fonctionnerait pas (car il n'a pas encore été fait) mais après avoir lu la réponse d' Alex Volovoy et réalisé que c'était la boîte d'alerte qui en était la cause. J'ai essayé d'ajouter une déclaration de retour juste après la fin dans ceif
bloc et cela a résolu le problème.Je pensais qu'une fois que vous aviez appelé terminer, il avait tout arrêté et terminé juste là, mais ce n'est pas le cas. Il semble aller à la fin du bloc de code dans lequel il se termine.
Donc, si vous voulez implémenter une situation où parfois cela se terminera avant de faire du code, vous devez mettre une déclaration de retour juste après la fin ou cela continuera et agira comme si la fin était appelée à la fin de la bloc de code pas où vous l'avez appelé. C'est pourquoi j'obtenais toutes ces erreurs étranges.
Si vous ne mettez pas le retour juste après que j'aie appelé terminer là-dedans, cela agira comme si vous l'aviez appelé après le
alert.show();
et donc il dirait que la fenêtre a fui en terminant juste après avoir fait apparaître la boîte de dialogue, même si c'est pas le cas, il le pense toujours.Je pensais ajouter ceci comme ici car cela montre que la commande d'arrivée a agi différemment alors je pensais que c'était le cas et je suppose qu'il y a d'autres personnes qui pensent la même chose que moi avant de découvrir cela.
la source
Ce n'est pas la réponse à la question mais elle est pertinente pour le sujet.
Si l'activité a défini un attribut dans le manifeste
puis après avoir exécuté onPause (), le contexte d'activité est perdu. Donc, toutes les vues utilisant ce contexte peuvent donner cette erreur.
la source
progessdialog.show()
.. etprogressdialog.hide()
dansasynctask
la même activité au lieu deonPause()
partiractivity
?? jetez un oeil à mon problème ... stackoverflow.com/questions/39332880/…Non seulement essayez d'afficher une alerte, mais elle peut également être invoquée lorsque vous terminez une instance particulière d'activité et essayez de démarrer une nouvelle activité / service ou essayez de l'arrêter.
Exemple:
la source
Généralement, ce problème se produit en raison de la boîte de dialogue de progression: vous pouvez résoudre ce problème en utilisant l'une des méthodes suivantes dans votre activité:
la source
J'ai eu le problème où j'ai terminé une activité alors qu'un ProgressDialog était toujours affiché.
Alors, cachez d'abord la boîte de dialogue, puis terminez l'activité.
la source
Essayez ce code:
la source
progressdialog.dismiss();
cela peut créer NullPointerException.Cela peut être si vous avez une erreur à la
doInBackground()
fonction et que vous avez ce code.Essayez enfin d'ajouter une boîte de dialogue. Au premier contrôle et
doInBackground()
fonction de correctionla source
Ce qui est arrivé à moi quand je me sers
ProgressDialog
dansAsyncTask
. En fait, j'utilise lahide()
méthodeonPostExecute
. Sur la base de la réponse de @Alex Volovoy, je dois utiliserdismiss()
avecProgressDialog
pour le supprimer dans onPostExecute et c'est fait.la source
AsyncTask
et que vous affichez leDialog
, alors quelque chose se produit qui fait l'Activity
appelonPause()
(peut-être une logique dans votre AsyncTask lui-même, comme un auditeur, alors il fuira. 2) Comme mentionné ci-dessus, leDialog
qui a été créé avec celaActivity
Context
n'est jamais rejeté et lesActivity
progrès.L'
Activity has leaked window that was originally added...
erreur " " se produit lorsque vous essayez d'afficher une alerte après que leActivity
soit effectivementfinished
.Vous avez deux options AFAIK:
dismiss()
ledialog
avant de quitter réellement votre activité.dialog
dans un thread différent et exécutez-lethread
(indépendamment du courantactivity
).la source
voici une solution lorsque vous voulez fermer AlertDialog mais ne voulez pas y faire référence dans l'activité.
la solution nécessite que vous ayez androidx.lifecycle dépendance dans votre projet (je crois qu'au moment du commentaire, c'est une exigence courante)
cela vous permet de déléguer le rejet de la boîte de dialogue à un objet externe (observateur), et vous n'avez plus besoin de vous en soucier, car il est automatiquement désabonné lorsque l'activité se termine. (voici la preuve: https://github.com/googlecodelabs/android-lifecycles/issues/5 ).
ainsi, l'observateur conserve la référence au dialogue et l'activité conserve la référence à l'observateur. lorsque "onPause" se produit - l'observateur rejette la boîte de dialogue et lorsque "onDestroy" se produit - l'activité supprime l'observateur, donc aucune fuite ne se produit (enfin, au moins je ne vois plus d'erreur dans logcat)
la source
Les exceptions de fuite de fenêtre ont deux raisons:
1) montrant la boîte de dialogue lorsque le contexte d'activité n'existe pas, pour résoudre ce problème, vous devez afficher la boîte de dialogue uniquement si vous êtes sûr que l'activité existe:
2) ne fermez pas la boîte de dialogue de manière appropriée, pour résoudre, utilisez ce code:
la source
Vous devez créer un
Progressdialog
objet dans laonPreExecute
méthode deAsyncTask
et vous devez le fairedismiss
dans laonPostExecute
méthode.la source
La meilleure solution consiste simplement à ajouter une boîte de dialogue pour essayer d'intercepter et de fermer la boîte de dialogue lorsqu'une exception se produit
la source
dialog.dismiss()
cela produira aussi une erreurDans mon cas, la raison était que j'avais oublié d'inclure une autorisation dans le fichier manifeste Android.
Comment ai-je découvert? Eh bien, comme @Bobby le dit dans un commentaire sous la réponse acceptée, faites défiler vers le haut jusqu'à vos journaux et vous verrez la première raison ou l'événement qui a vraiment déclenché l'exception. Apparemment, le message "L'activité a fui la fenêtre qui a été ajoutée à l'origine" n'est qu'une exception résultant de la première exception.
la source
Essayez le code ci-dessous, cela fonctionnera à chaque fois que vous fermerez la boîte de dialogue de progression et il verra si son instance est disponible ou non.
la source
La meilleure solution est de mettre ceci avant d'afficher
progressbar
ouprogressDialog
la source
Assurez-vous simplement que votre activité ne se ferme pas de façon inattendue en raison de certaines exceptions levées quelque part dans votre code. Généralement, cela se produit dans une tâche asynchrone lorsque l'activité fait face à une fermeture forcée dans la méthode doinBackground, puis que asynctask retourne à la méthode onPostexecute.
la source
J'ai une autre solution pour cela, et je voudrais savoir si cela vous semble valable: au lieu de rejeter dans onDestroy, qui semble être la solution principale, j'étends ProgressDialog ...
C'est préférable, AFAIC, car vous n'avez pas besoin de maintenir la boîte de dialogue de progression en tant que membre, il suffit de tirer (afficher) et d'oublier
la source