Apa kesalahan ini, dan mengapa itu terjadi?
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
sumber
sumber
Jawaban:
Anda mencoba menampilkan Dialog setelah Anda keluar dari Aktivitas.
[EDIT]
Pertanyaan ini adalah salah satu pencarian teratas di google untuk pengembang android, oleh karena itu Menambahkan beberapa poin penting dari komentar, yang mungkin lebih bermanfaat bagi simpatisan masa depan tanpa membahas percakapan komentar secara mendalam.
Jawaban 1 :
Jawaban 2
Jawaban 3
sumber
Solusinya adalah memanggil
dismiss()
yangDialog
Anda buatviewP.java:183
sebelum keluar dariActivity
, misalnya dionPause()
. SemuaWindow
sDialog
harus ditutup sebelum meninggalkan aActivity
.sumber
Jika Anda menggunakan
AsyncTask
, mungkin pesan log itu bisa menipu. Jika Anda melihat log Anda, Anda mungkin menemukan kesalahan lain, mungkin satu dalamdoInBackground()
metode AndaAsyncTask
, yaitu membuat arus AndaActivity
meledak, dan dengan demikian setelahAsyncTask
kembali .. well, Anda tahu sisanya. Beberapa pengguna lain sudah menjelaskan bahwa di sini :-)sumber
doInBackground
dariAsyncTask
kelas tapi tanpa mendeklarasikan dalamAndroidManifest
file menggunakan propertiandroid:name
seperti ini:android:name="my.package.MyApplicationClass"
. Praktik yang baik saat menggunakannyaAsyncTask
selalu ingat untuk membuat peringatan Anda di dalam metodeonPreExecute
dan mengabaikannyaonPostExecute
.Saya memicu kesalahan ini dengan panggilan yang salah
hide()
alih-alihdismiss()
padaAlertDialog
.sumber
Anda bisa mendapatkan pengecualian ini hanya dengan kesalahan sederhana / bodoh, dengan (misalnya) panggilan tidak sengaja
finish()
setelah menampilkanAlertDialog
, jika Anda melewatkan pernyataan panggilan balik dalam pernyataan beralih ...The
finish()
Metode akan menutupActivity
, tetapiAlertDialog
masih menampilkan!Jadi ketika Anda menatap kode dengan saksama, mencari masalah threading yang buruk atau pengkodean kompleks dan semacamnya, jangan lupakan hutan untuk melihat pepohonan. Kadang-kadang bisa menjadi sesuatu yang sederhana dan bodoh seperti pernyataan istirahat yang hilang. :)
sumber
Jawaban atas pertanyaan ini semuanya benar, tetapi sedikit membingungkan bagi saya untuk benar-benar mengerti mengapa. Setelah bermain-main selama sekitar 2 jam alasan kesalahan ini (dalam kasus saya) mengenai saya:
Anda sudah tahu, dari membaca jawaban lain, bahwa
X has leaked window DecorView@d9e6131[]
kesalahan berarti dialog terbuka ketika aplikasi Anda ditutup. Tapi kenapa?Bisa jadi, aplikasi Anda mogok karena alasan lain saat dialog Anda terbuka
Ini mengarah pada penutupan aplikasi Anda karena beberapa bug dalam kode Anda, yang menyebabkan dialog tetap terbuka pada saat yang sama dengan aplikasi Anda ditutup karena kesalahan lainnya.
Jadi, perhatikan logika Anda. Selesaikan kesalahan pertama, dan kemudian kesalahan kedua akan menyelesaikan sendiri
Satu kesalahan menyebabkan yang lain, yang menyebabkan yang lain, seperti DOMINOS!
sumber
Masalah ini muncul ketika mencoba menampilkan Dialog setelah Anda keluar dari suatu Kegiatan.
Saya baru saja memecahkan masalah ini hanya dengan menuliskan kode berikut:
Pada dasarnya, dari kelas mana Anda memulai progressDialog, timpa metode onDestroy dan lakukan cara ini. Itu memecahkan masalah "Aktivitas telah bocor jendela".
sumber
Baru-baru ini saya menghadapi masalah yang sama.
Alasan di balik masalah ini adalah bahwa kegiatan ditutup sebelum dialog diberhentikan. Ada berbagai alasan untuk hal di atas terjadi. Yang disebutkan dalam posting di atas juga benar.
Saya masuk ke suatu situasi, karena di utas, saya memanggil fungsi yang melempar pengecualian. Karena itu jendela diberhentikan dan karenanya pengecualian.
sumber
Singkirkan dialog saat aktivitas dihancurkan
sumber
Ini bisa membantu.
sumber
Saya memiliki pesan kesalahan yang sama dan tidak tahu mengapa. Diberi petunjuk dari jawaban sebelumnya, saya mengubah panggilan non-GUI saya ke mDialog.finish () menjadi mDialog.dismiss () dan kesalahannya hilang. Ini tidak memengaruhi perilaku widget saya, tetapi membingungkan dan bisa saja menandai kebocoran memori yang penting.
sumber
Saya mendapatkan log ini di aplikasi pemutar video saya. Pesan-pesan ini dibuang saat pemutar video ditutup. Menariknya, saya biasa mendapatkan log ini sekali dalam beberapa kali secara acak. Juga aplikasi saya tidak terlibat
progressdialog
. Akhirnya, saya menyelesaikan masalah ini dengan implementasi di bawah ini.Timpa
OnPause
panggilan with tomVideoView.pause()
dan setvisibility
toGONE
. Dengan cara ini saya bisa menyelesaikan masalah "Activity has leaked window
" log error.sumber
Saya mengalami masalah yang sama dan menemukan halaman ini, dan sementara situasi saya berbeda, saya menelepon
finish
dari aif
blok sebelum mendefinisikan kotak tanda.Jadi, hanya menelepon
dismiss
tidak akan berhasil (karena belum dibuat) tetapi setelah membaca jawaban Alex Volovoy dan menyadari itu adalah kotak peringatan yang menyebabkannya. Saya mencoba menambahkan pernyataan kembali tepat setelah selesai di dalamnyaif
blok itu dan itu memperbaiki masalah.Saya pikir begitu Anda menelepon selesai, berhenti semuanya dan selesai di sana, tetapi tidak. Tampaknya pergi ke ujung blok kode itu kemudian selesai.
Jadi, jika Anda ingin menerapkan situasi di mana kadang-kadang itu akan selesai sebelum melakukan beberapa kode Anda harus meletakkan pernyataan kembali tepat setelah selesai atau itu akan terus berjalan dan dan bertindak seperti selesai dipanggil pada akhir blok kode bukan tempat Anda menyebutnya. Itulah sebabnya saya mendapatkan semua kesalahan aneh itu.
Jika Anda tidak mengembalikan tepat setelah saya menelepon selesai di sana, itu akan bertindak seolah-olah Anda telah memanggilnya setelah
alert.show();
dan karenanya akan mengatakan bahwa jendela bocor dengan menyelesaikan tepat setelah Anda membuat dialog muncul, meskipun itu tidak demikian, masih berpikir demikian.Saya pikir saya akan menambahkan ini di sini karena ini menunjukkan perintah selesai bertindak berbeda maka saya pikir itu terjadi dan saya kira ada orang lain yang berpikir sama seperti yang saya lakukan sebelum saya menemukan ini.
sumber
Ini bukan jawaban untuk pertanyaan tetapi relevan dengan topik.
Jika aktivitas telah menetapkan atribut dalam Manifest
kemudian setelah mengeksekusi onPause (), konteks aktivitas hilang. Jadi semua tampilan yang menggunakan konteks ini dapat memberikan kesalahan ini.
sumber
progessdialog.show()
.. danprogressdialog.hide()
dalamasynctask
aktivitas yang sama, bukanonPause()
dariactivity
?? lihat masalah saya ... stackoverflow.com/questions/39332880/…Tidak hanya mencoba menampilkan peringatan tetapi juga dapat dipanggil ketika Anda menyelesaikan contoh aktivitas tertentu dan mencoba memulai aktivitas / layanan baru atau mencoba menghentikannya.
Contoh:
sumber
Secara umum masalah ini terjadi karena dialog progres: Anda dapat menyelesaikan ini dengan menggunakan salah satu metode berikut dalam aktivitas Anda:
sumber
Punya masalah di mana saya menyelesaikan Kegiatan ketika ProgressDialog masih ditampilkan.
Jadi pertama-tama sembunyikan Dialog dan kemudian selesaikan aktivitas.
sumber
Coba kode ini:
sumber
progressdialog.dismiss();
ini dapat membuat NullPointerException.Ini bisa terjadi jika Anda memiliki kesalahan di
doInBackground()
fungsi dan memiliki kode ini.Coba tambahkan dialog pada akhirnya. Pada awalnya periksa dan perbaiki
doInBackground()
fungsisumber
Ini terjadi pada saya ketika saya menggunakan
ProgressDialog
diAsyncTask
. Sebenarnya saya menggunakanhide()
metode dalamonPostExecute
. Berdasarkan jawaban @Alex Volovoy saya perlu menggunakandismiss()
denganProgressDialog
untuk menghapusnya di onPostExecute dan selesai.sumber
AsyncTask
dan menunjukkanDialog
, maka sesuatu terjadi yang membuatActivity
panggilanonPause()
(mungkin beberapa logika di AsyncTask Anda sendiri, seperti pendengar, maka akan bocor. 2) Seperti disebutkan di atas,Dialog
yang dibuat dengan yangActivity
Context
tidak pernah diberhentikan danActivity
bergerak terus.Kesalahan "
Activity has leaked window that was originally added...
" terjadi ketika Anda mencoba menunjukkan peringatan setelahActivity
secara efektiffinished
.Anda memiliki dua opsi AFAIK:
dismiss()
padadialog
sebelum benar-benar keluar aktivitas Anda.dialog
di utas yang berbeda dan jalankan di situthread
(terlepas dari arusactivity
).sumber
di sini adalah solusi ketika Anda ingin mengabaikan AlertDialog tetapi tidak ingin menyimpan referensi dalamnya dalam aktivitas.
solusi mengharuskan Anda memiliki androidx.lifecycle ketergantungan di proyek Anda (saya percaya pada saat komentar itu adalah persyaratan umum)
ini memungkinkan Anda untuk mendelegasikan pemberhentian dialog ke objek eksternal (pengamat), dan Anda tidak perlu lagi mempedulikannya, karena ini berhenti berlangganan otomatis ketika aktivitas mati. (Ini buktinya: https://github.com/googlecodelabs/android-lifecycles/issues/5 ).
jadi, pengamat menyimpan referensi untuk dialog, dan aktivitas menyimpan referensi ke pengamat. ketika "onPause" terjadi - pengamat menolak dialog, dan ketika "onDestroy" terjadi - aktivitas menghapus pengamat, jadi tidak ada kebocoran yang terjadi (yah, setidaknya saya tidak melihat kesalahan di logcat lagi)
sumber
Pengecualian kebocoran jendela memiliki dua alasan:
1) menampilkan dialog ketika Konteks Kegiatan tidak ada, untuk menyelesaikan ini Anda harus menunjukkan dialog hanya Anda yakin Kegiatan ada:
2) tidak mengabaikan dialog dengan tepat, untuk menyelesaikan penggunaan kode ini:
sumber
Anda harus membuat
Progressdialog
objek dalamonPreExecute
metodeAsyncTask
dan Anda harusdismiss
padaonPostExecute
metode.sumber
Solusi terbaik adalah menambahkan dialog di dialog coba tangkap dan abaikan saat pengecualian terjadi
sumber
dialog.dismiss()
akan menghasilkan kesalahan jugaDalam kasus saya, alasannya adalah saya lupa memasukkan izin dalam file manifes Android.
Bagaimana saya mengetahuinya? Yah, sama seperti @ Bobby mengatakan dalam komentar di bawah jawaban yang diterima, cukup gulir lebih jauh ke log Anda dan Anda akan melihat alasan pertama atau peristiwa yang benar-benar melemparkan Pengecualian. Tampaknya, pesan "Jendela aktivitas bocor yang semula ditambahkan" hanyalah Pengecualian yang dihasilkan dari apa pun Pengecualian pertama.
sumber
Coba kode di bawah ini, ini akan berfungsi kapan saja Anda akan mengabaikan dialog progres dan ia akan melihat apakah instansinya tersedia atau tidak.
sumber
Solusi terbaik adalah meletakkan ini sebelum ditampilkan
progressbar
atauprogressDialog
sumber
Pastikan aktivitas Anda tidak menutup secara tak terduga karena beberapa pengecualian yang muncul di suatu tempat dalam kode Anda. Umumnya itu terjadi dalam tugas async ketika aktivitas menghadapi penutupan paksa dalam metode doinBackground dan kemudian asynctask kembali ke metode onPostexecute.
sumber
Saya punya solusi lain untuk ini, dan ingin tahu apakah itu berlaku bagi Anda: daripada mengabaikan onDestroy, yang tampaknya menjadi solusi utama, saya memperluas ProgressDialog ...
Ini lebih disukai, AFAIC, karena Anda tidak perlu menahan dialog progres sebagai anggota, cukup jalankan (tampilkan) dan lupakan
sumber