Co to za błąd i dlaczego się zdarza?
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
źródło
źródło
Odpowiedzi:
Próbujesz wyświetlić okno dialogowe po wyjściu z działania.
[EDYTOWAĆ]
To pytanie jest jednym z najlepszych wyników wyszukiwania w Google dla programistów Androida, dlatego dodanie kilku ważnych punktów z komentarzy, które mogą być bardziej przydatne dla przyszłego badacza bez pogłębiania rozmowy o komentarzach.
Odpowiedź 1 :
Odpowiedź 2
Odpowiedź 3
źródło
Rozwiązaniem jest wezwanie
dismiss()
naDialog
utworzony wviewP.java:183
przed opuszczeniemActivity
, nponPause()
. WszystkieWindow
s &Dialog
s powinny zostać zamknięte przed opuszczeniemActivity
.źródło
Jeśli używasz
AsyncTask
, prawdopodobnie ten komunikat dziennika może wprowadzać w błąd. Jeśli spojrzysz na swój dziennik, możesz znaleźć inny błąd, prawdopodobnie w twojejdoInBackground()
metodzieAsyncTask
, który powoduje, że twój prądActivity
wysadza się w powietrze, a zatem poAsyncTask
powrocie .. cóż, znasz resztę. Niektórzy inni użytkownicy już to wyjaśnili tutaj :-)źródło
doInBackground
zAsyncTask
klasy, ale bez zadeklarować wAndroidManifest
pliku przy użyciu właściwościandroid:name
takiego:android:name="my.package.MyApplicationClass"
. Dobrą praktyką podczas korzystania zAsyncTask
niego jest zawsze pamiętaj o utworzeniu alertu w metodzieonPreExecute
i odrzuceniu goonPostExecute
.Wywołałem ten błąd przez pomyłkowe wywołanie
hide()
zamiastdismiss()
naAlertDialog
.źródło
Możesz uzyskać ten wyjątek, po prostu przez zwykły / głupi błąd, (na przykład) przypadkowo dzwoniąc
finish()
po wyświetleniuAlertDialog
, jeśli przegapisz instrukcję przerwania w instrukcji przełączania ...finish()
Metoda będzie zamknąćActivity
, aleAlertDialog
nadal wyświetla!Więc kiedy wpatrujesz się uważnie w kod, szukasz złych wątków lub skomplikowanego kodowania i tym podobnych, nie trać z lasu lasu. Czasami może to być coś tak prostego i głupiego jak brakująca instrukcja break. :)
źródło
Wszystkie odpowiedzi na to pytanie były poprawne, ale trochę mylące dla mnie, aby zrozumieć, dlaczego. Po około 2 godzinach gry powód tego błędu (w moim przypadku) uderzył mnie:
Po przeczytaniu innych odpowiedzi wiesz już, że
X has leaked window DecorView@d9e6131[]
błąd oznacza, że okno dialogowe było otwarte po zamknięciu aplikacji. Ale dlaczego?Możliwe, że aplikacja uległa awarii z innego powodu, gdy okno dialogowe było otwarte
Prowadzi to do zamknięcia aplikacji z powodu błędu w kodzie, co powoduje, że okno dialogowe pozostaje otwarte w tym samym czasie, co aplikacja zamknięta z powodu innego błędu.
Przejrzyj swoją logikę. Rozwiąż pierwszy błąd, a następnie drugi błąd sam się rozwiąże
Jeden błąd powoduje inny, co powoduje inny, np. DOMINOS!
źródło
Ten problem pojawia się podczas próby wyświetlenia okna dialogowego po wyjściu z działania.
Właśnie rozwiązałem ten problem, zapisując następujący kod:
Zasadniczo, od której klasy zacząłeś progressDialog, zastąp metodę onDestroy i zrób to w ten sposób. Rozwiązano problem z „Aktywnością wyciekło okno”.
źródło
Ostatnio napotkałem ten sam problem.
Przyczyną tego problemu jest zamknięcie działania przed zamknięciem okna dialogowego. Istnieje wiele przyczyn takiego stanu rzeczy. Te wymienione w powyższych postach są również poprawne.
Wpadłem w sytuację, ponieważ w wątku wywoływałem funkcję, która rzucała wyjątek. Z powodu którego okno było usuwane, a zatem wyjątek.
źródło
Zamknij okno dialogowe, gdy aktywność zostanie zniszczona
źródło
To może pomóc.
źródło
Miałem ten sam niejasny komunikat o błędzie i nie miałem pojęcia, dlaczego. Biorąc pod uwagę wskazówki z poprzednich odpowiedzi, zmieniłem swoje wywołania inne niż GUI na mDialog.finish () na mDialog.dismiss () i błędy zniknęły. Nie miało to wpływu na zachowanie mojego widgetu, ale było niepokojące i mogło oznaczać ważny wyciek pamięci.
źródło
Otrzymywałem te dzienniki w mojej aplikacji odtwarzacza wideo. Te wiadomości zostały wyrzucone, gdy odtwarzacz wideo był zamknięty. Co ciekawe, logi te pobierałem raz na kilka serii w losowy sposób. Również moja aplikacja nie dotyczy
progressdialog
. Wreszcie obejrzałem ten problem z poniższą implementacją.Zastąp opcję „
OnPause
call call”mVideoView.pause()
i „setvisibility
to”GONE
. W ten sposób mogłem rozwiązać problem zActivity has leaked window
błędem dziennika.źródło
Miałem ten sam problem i znalazłem tę stronę i chociaż moja sytuacja była inna, zadzwoniłem
finish
zif
bloku, zanim zdefiniował pole alertu.Tak więc zwykłe dzwonienie
dismiss
nie zadziałałoby (bo jeszcze tego nie zrobiono), ale po przeczytaniu odpowiedzi Alexa Volovoya i zrozumieniu, że to ona spowodowała alarm. Próbowałem dodać instrukcję return zaraz po zakończeniu wewnątrz tegoif
bloku i to rozwiązało problem.Myślałem, że kiedy nazwiesz „koniec”, wszystko zatrzymało się i skończyło się w tym miejscu, ale tak się nie dzieje. Wydaje się, że kończy się na końcu bloku kodu, w którym się kończy.
Tak więc, jeśli chcesz zaimplementować sytuację, w której czasami kończy się przed wykonaniem kodu, musisz umieścić instrukcję return zaraz po zakończeniu lub będzie kontynuowała działanie i działała tak, jakby koniec został wywołany na końcu blok kodu nie w miejscu, w którym go nazwiesz. Właśnie dlatego dostaję te wszystkie dziwne błędy.
Jeśli nie umieścisz zwrotu zaraz po tym, jak wezwałem tam wykończenie, będzie to działało tak, jakbyś nazwał go po tym,
alert.show();
a zatem powiedziałoby, że okno jest nieszczelne, kończąc zaraz po tym, jak pojawiło się okno dialogowe. nie w tym przypadku, nadal tak jest.Pomyślałem, że dodam to tutaj, ponieważ pokazuje, że polecenie zakończenia działało inaczej, niż myślałem, że tak, i sądzę, że są inni ludzie, którzy myślą tak samo, jak ja, zanim to odkryłem.
źródło
To nie jest odpowiedź na pytanie, ale odnosi się do tematu.
Jeśli działanie zdefiniowało atrybut w Manifeście
następnie po wykonaniu onPause () kontekst działania zostaje utracony. Więc wszystkie widoki używające tego kontekstu mogą dawać ten błąd.
źródło
progessdialog.show()
.. iprogressdialog.hide()
wasynctask
tej samej działalności, a nieonPause()
zactivity
?? spójrz na mój problem ... stackoverflow.com/questions/39332880/…Nie tylko próbuj wyświetlić alert, ale można go również wywołać po zakończeniu określonego wystąpienia aktywności i próbie rozpoczęcia nowej aktywności / usługi lub próby jej zatrzymania.
Przykład:
źródło
Zasadniczo ten problem występuje z powodu okna dialogowego postępu: możesz rozwiązać ten problem, używając jednej z następujących metod w swoim działaniu:
źródło
Wystąpił problem polegający na tym, że zakończyłem działanie, gdy program ProgressDialog był nadal wyświetlany.
Najpierw ukryj okno dialogowe, a następnie zakończ działanie.
źródło
Wypróbuj ten kod:
źródło
progressdialog.dismiss();
może to stworzyć wyjątek NullPointerException.Może się tak zdarzyć, jeśli masz błąd w
doInBackground()
działaniu i masz ten kod.Spróbuj w końcu dodać okno dialogowe. Na początku sprawdź i napraw
doInBackground()
funkcjęźródło
To zdarzyło się do mnie, kiedy używam
ProgressDialog
wAsyncTask
. Właściwie używamhide()
metody wonPostExecute
. Na podstawie odpowiedzi z @Alex Volovoy muszę korzystaćdismiss()
zProgressDialog
usunięcia go w onPostExecute i jego zrobienia.źródło
AsyncTask
i pokazujeszDialog
, to dzieje się coś, co wywołujeActivity
wywołanieonPause()
(być może logika w twoim AsyncTask, jak słuchacz, wtedy wycieknie. 2) Jak wspomniano powyżej, to,Dialog
co zostało utworzone za pomocą tego,Activity
Context
nigdy nie jest zwolniony iActivity
idzie dalej.Activity has leaked window that was originally added...
Błąd „ ” występuje, gdy próbujesz pokazać alert poActivity
skutecznymfinished
.Masz dwie opcje AFAIK:
dismiss()
nadialog
zanim faktycznie wychodzenia swoją aktywność.dialog
w innym wątku i uruchom na nimthread
(niezależnie od prąduactivity
).źródło
oto rozwiązanie, gdy chcesz odrzucić AlertDialog, ale nie chcesz zachować odwołania do niego w działaniu.
rozwiązanie wymaga posiadania zależności androidx.lifecycle w swoim projekcie (uważam, że w momencie komentarza jest to powszechny wymóg)
pozwala to na delegowanie odrzucenia okna dialogowego do obiektu zewnętrznego (obserwatora) i nie musisz się już tym przejmować, ponieważ jest automatycznie wypisywane po zakończeniu aktywności. (tutaj jest dowód: https://github.com/googlecodelabs/android-lifecycles/issues/5 ).
więc obserwator zachowuje odniesienie do okna dialogowego, a aktywność zachowuje odniesienie do obserwatora. kiedy zdarza się „onPause” - obserwator zamyka okno dialogowe, a gdy zdarza się „onDestroy” - aktywność usuwa obserwatora, więc nie dochodzi do wycieku (cóż, przynajmniej nie widzę już błędu w logcat)
źródło
Wyjątki związane z wyciekaniem okien mają dwa powody:
1) wyświetlenie okna dialogowego, gdy kontekst działania nie istnieje, aby go rozwiązać, powinieneś pokazać okno dialogowe tylko wtedy, gdy masz pewność, że działanie istnieje:
2) nie odrzuć odpowiednio okna dialogowego, aby rozwiązać, użyj tego kodu:
źródło
Musisz zrobić
Progressdialog
obiektonPreExecute
metodąAsyncTask
i powinieneśdismiss
to zrobićonPostExecute
metodą.źródło
Najlepszym rozwiązaniem jest dodanie okna dialogowego podczas próby złapania i odrzucenia okna dialogowego, gdy wystąpi wyjątek
źródło
dialog.dismiss()
spowoduje błądW moim przypadku powodem było to, że zapomniałem dołączyć pozwolenie do pliku manifestu Androida.
Jak się dowiedziałem? Cóż, tak jak @Bobby mówi w komentarzu pod zaakceptowaną odpowiedzią, po prostu przewiń dalej do swoich dzienników, a zobaczysz pierwszy powód lub zdarzenie, które naprawdę spowodowało wyjątek. Najwyraźniej komunikat „Aktywność wyciekła okno, które zostało pierwotnie dodane” to tylko wyjątek wynikający z pierwszego wyjątku.
źródło
Wypróbuj poniższy kod, zadziała za każdym razem, gdy odrzucisz dialog postępu i zobaczysz, czy jego instancja jest dostępna, czy nie.
źródło
Najlepszym rozwiązaniem jest umieszczenie tego przed pokazaniem
progressbar
lubprogressDialog
źródło
Upewnij się tylko, że twoja aktywność nie niespodziewanie się kończy z powodu wyjątków zgłoszonych gdzieś w kodzie. Zasadniczo dzieje się tak w zadaniu asynchronicznym, gdy działanie napotyka wymuszone zamknięcie w metodzie doinBackground, a następnie asynctask powraca do metody onPostexecute.
źródło
Mam na to inne rozwiązanie i chciałbym wiedzieć, czy wydaje się to dla ciebie ważne: zamiast zwolnienia w onDestroy, który wydaje się być wiodącym rozwiązaniem, rozszerzam ProgressDialog ...
Jest to preferowane, AFAIC, ponieważ nie musisz utrzymywać dialogu postępu jako członek, po prostu odpal (pokaż) i zapomnij
źródło