Что это за ошибка и почему она происходит?
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
источник
источник
Ответы:
Вы пытаетесь показать диалог после выхода из действия.
[РЕДАКТИРОВАТЬ]
Этот вопрос является одним из самых популярных в Google для разработчиков Android, поэтому добавьте несколько важных моментов из комментариев, которые могут оказаться более полезными для будущего исследователя, не вдаваясь в подробности обсуждения комментариев.
Ответ 1 :
Ответ 2
Ответ 3
источник
Решение состоит в том, чтобы позвонить
dismiss()
наDialog
созданный вамиviewP.java:183
до выходаActivity
, например, вonPause()
. ВсеWindow
S &Dialog
S должны быть закрыты, прежде чем покинутьActivity
.источник
Если вы используете
AsyncTask
, вероятно, это сообщение журнала может быть обманчивым. Если вы посмотрите в своем журнале, вы можете найти еще одну ошибку, возможно, в вашемdoInBackground()
методеAsyncTask
, которая заставляет ваш токActivity
взорваться, и, таким образом, когда онAsyncTask
возвращается ... ну, вы знаете все остальное. Некоторые другие пользователи уже объяснили это здесь :-)источник
doInBackground
вAsyncTask
классе , но без объявим его вAndroidManifest
файл , используя свойствоandroid:name
как это:android:name="my.package.MyApplicationClass"
. Хорошей практикой приAsyncTask
его использовании всегда является создание экземпляра вашего оповещения внутри методаonPreExecute
и его отключениеonPostExecute
.Я вызвал эту ошибку, по ошибке позвонив,
hide()
а неdismiss()
наAlertDialog
.источник
Вы можете получить это исключение простой / тупой ошибкой, например, случайно вызвав
finish()
после отображения оператораAlertDialog
, если вы пропустите оператор прерывания вызова в операторе switch ...finish()
Метод будет закрытьActivity
, ноAlertDialog
до сих пор отображения!Поэтому, когда вы пристально смотрите на код, ищите проблемы с многопоточностью или сложное кодирование и тому подобное, не упускайте из виду лес за деревьями. Иногда это может быть что-то столь же простое и глупое, как пропущенное выражение разрыва :)
источник
Все ответы на этот вопрос были правильными, но я немного сбивался с толку, чтобы понять, почему. После игры около 2 часов причина этой ошибки (в моем случае) меня ударила:
Из прочтения других ответов вы уже знаете, что
X has leaked window DecorView@d9e6131[]
ошибка означает, что диалоговое окно было открыто при закрытии приложения. Но почему?Может случиться так, что ваше приложение зависло по какой-то другой причине, когда ваш диалог был открыт
Это приводит к закрытию вашего приложения из-за некоторой ошибки в вашем коде, которая приводит к тому, что диалоговое окно остается открытым одновременно с закрытием вашего приложения из-за другой ошибки.
Итак, просмотрите свою логику. Решите первую ошибку, и тогда вторая ошибка решит сама
Одна ошибка вызывает другую, которая вызывает другую, как DOMINOS!
источник
Эта проблема возникает при попытке показать диалоговое окно после выхода из действия.
Я просто решил эту проблему, просто записав следующий код:
По сути, из какого класса вы начали progressDialog, переопределите метод onDestroy и сделайте так. Это решило проблему "активность утекла окно".
источник
Я недавно столкнулся с той же проблемой.
Причина этой проблемы заключается в том, что действие закрывается до закрытия диалога. Есть много причин, по которым это может произойти. Те, что упомянуты в постах выше, также верны.
Я попал в ситуацию, потому что в потоке я вызывал функцию, которая генерировала исключение. Из-за чего окно было закрыто и отсюда исключение.
источник
Закрыть диалог, когда активность уничтожена
источник
Это может помочь.
источник
У меня было такое же неясное сообщение об ошибке, и я понятия не имел, почему. Учитывая подсказки из предыдущих ответов, я изменил свои вызовы не-GUI на mDialog.finish (), чтобы быть mDialog.dismiss (), и ошибки исчезли. Это не влияло на поведение моего виджета, но сбивало с толку и вполне могло указывать на серьезную утечку памяти.
источник
Я получал эти журналы в моем приложении видеоплеера. Эти сообщения были выброшены, когда видеоплеер был закрыт. Интересно, что я получал эти журналы один раз за несколько запусков случайным образом. Также мое приложение не привлекает ни к чему
progressdialog
. Наконец, я обошел эту проблему с помощью реализации ниже.Переопределить
OnPause
с вызовомmVideoView.pause()
и наборvisibility
кGONE
. Таким образом, я мог решить проблему сActivity has leaked window
ошибкой журнала.источник
У меня возникла та же проблема, и я нашел эту страницу, и хотя моя ситуация отличалась, я позвонил
finish
изif
блока, прежде чем он определил окно предупреждения.Таким образом, простой вызов
dismiss
не сработает (поскольку это еще не было сделано), но после прочтения ответа Алексея Волового и понимания того, что это окно предупреждения, вызывает его. Я попытался добавить оператор возврата сразу после финиша внутри этогоif
блока, и это решило проблему.Я думал, что как только вы позвоните «закончить», это остановит все и сразу же закончится, но это не так. Похоже, что он доходит до конца блока кода, в котором он завершается.
Итак, если вы хотите реализовать ситуацию, когда иногда он завершает работу перед выполнением некоторого кода, вы должны поместить оператор return сразу после завершения или он будет продолжать работать и будет действовать так, как если бы конец был вызван в конце блок кода не там, где вы его назвали. Вот почему я получаю все эти странные ошибки.
Если вы не поместите возврат сразу после того, как я вызвал финиш, он будет действовать так, как если бы вы вызвали его после,
alert.show();
и, следовательно, он скажет, что окно просочилось после финиша сразу после того, как вы открыли диалоговое окно, даже если это не тот случай, все равно думаю, что это так.Я думал, что добавлю это здесь, так как это показывает, что команда финиша действовала иначе, чем я думал, и я предположил, что есть другие люди, которые думают так же, как и я, прежде чем я обнаружил это.
источник
Это не ответ на вопрос, но он имеет отношение к теме.
Если действие определило атрибут в манифесте
затем после выполнения onPause () контекст действия теряется. Таким образом, все представления, использующие этот контекст, могут выдавать эту ошибку.
источник
progessdialog.show()
... иprogressdialog.hide()
вasynctask
той же деятельности, а неonPause()
изactivity
?? взгляните на мою проблему ... stackoverflow.com/questions/39332880/…Не только попытайтесь показать предупреждение, но и вызвать его, когда вы закончите конкретный экземпляр действия и попытаетесь запустить новое действие / службу или попытаться остановить его.
Пример:
источник
Обычно эта проблема возникает из-за диалогового окна прогресса: вы можете решить эту проблему, используя любой из следующих методов в вашей деятельности:
источник
У меня была проблема, когда я закончил Activity, когда ProgressDialog все еще показывался.
Поэтому сначала скройте диалог, а затем завершите упражнение.
источник
Попробуйте этот код:
источник
progressdialog.dismiss();
это может создать NullPointerException.Это может быть, если у вас есть ошибка в
doInBackground()
функции и есть этот код.Попробуйте добавить диалог, наконец. Сначала проверьте и исправьте
doInBackground()
функциюисточник
Это случилось со мной, когда я использую
ProgressDialog
вAsyncTask
. На самом деле я используюhide()
метод вonPostExecute
. На основании ответа @Alex Volovoy мне нужно использоватьdismiss()
с ,ProgressDialog
чтобы удалить его в onPostExecute и его сделали.источник
AsyncTask
и вы показываетеDialog
, то происходит что-то, что делаетActivity
вызовonPause()
(может быть, какая-то логика в самой AsyncTask, например, слушатель, тогда он будет просачиваться. 2) Как упоминалось выше, то,Dialog
что было создано с этимActivity
Context
, никогда не будет уволен иActivity
движется дальше.«
Activity has leaked window that was originally added...
» Возникает ошибка, когда вы пытаетесь показать предупреждение после того,Activity
как эффективноfinished
.У вас есть два варианта AFAIK:
dismiss()
того,dialog
как вы по-настоящему выйдете из своей активности.dialog
в другой поток и запустите егоthread
(независимо от текущегоactivity
).источник
Вот решение, когда вы хотите закрыть AlertDialog, но не хотите сохранять ссылку на него внутри действия.
решение требует, чтобы у вас была зависимость androidx.lifecycle в вашем проекте (я считаю, что в момент комментария это общее требование)
это позволяет вам делегировать отклонение диалога внешнему объекту (наблюдателю), и вам больше не нужно об этом заботиться, потому что он автоматически отписывается, когда активность прекращается. (вот доказательство: https://github.com/googlecodelabs/android-lifecycles/issues/5 ).
таким образом, наблюдатель сохраняет ссылку на диалог, а активность сохраняет ссылку на наблюдателя. когда происходит «onPause» - наблюдатель закрывает диалоговое окно, а когда «onDestroy» происходит - действие удаляет наблюдателя, поэтому утечки не происходит (ну, по крайней мере, я больше не вижу ошибки в logcat)
источник
Окно утечки имеет две причины:
1) показ диалогового окна, когда контекст активности не существует, для решения этой проблемы вы должны показать диалог, только если вы уверены, что активность существует:
2) не закрывать диалог соответствующим образом, для решения используйте этот код:
источник
Вы должны сделать
Progressdialog
объект вonPreExecute
методе,AsyncTask
и вы должныdismiss
это сделать поonPostExecute
методу.источник
Лучшее решение - просто добавить диалог в диалоге try catch и dismiss при возникновении исключения
источник
dialog.dismiss()
это также приведет к ошибкеВ моем случае причина была в том, что я забыл включить разрешение в файл манифеста Android.
Как я узнал? Ну, точно так же, как @Bobby говорит в комментарии под принятым ответом, просто прокрутите дальше до своих журналов, и вы увидите первую причину или событие, которое действительно вызвало исключение. По-видимому, сообщение «Активность просочилось окно, которое было первоначально добавлено» является только исключением, которое возникло из того, что первое исключение.
источник
Попробуйте приведенный ниже код, он будет работать каждый раз, когда вы будете закрывать диалог прогресса, и он увидит, доступен ли его экземпляр или нет.
источник
Лучшее решение это поставить перед показом
progressbar
илиprogressDialog
источник
Просто убедитесь, что ваша деятельность не закрывается неожиданно из-за некоторых исключений, возникающих где-то в вашем коде. Обычно это происходит в асинхронной задаче, когда действие сталкивается с принудительным закрытием в методе doinBackground, а затем asynctask возвращается к методу onPostexecute.
источник
У меня есть другое решение для этого, и я хотел бы знать, если оно кажется вам действительным: вместо того, чтобы уволить в onDestroy, который, кажется, является ведущим решением, я расширяю ProgressDialog ...
Это предпочтительнее, AFAIC, потому что вам не нужно держать диалог прогресса в качестве участника, просто запустите (показать) и забудьте
источник