02-19 15:08:02.228: E/WindowManager(22172): Activity com.test.activity.TestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@427bebc8 that was originally added here 02-19 15:08:02.228: E/WindowManager(22172): android.view.WindowLeaked: Activity com.test.activity.TestActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@427bebc8 that was originally added here 02-19 15:08:02.228: E/WindowManager(22172): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:438) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:292) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:149) 02-19 15:08:02.228: E/WindowManager(22172): at android.view.Window$LocalWindowManager.addView(Window.java:558) 02-19 15:08:02.228: E/WindowManager(22172): at android.app.Dialog.show(Dialog.java:316) 02-19 15:08:02.228: E/WindowManager(22172): at com.test.activity.TestActivity.onError(TestActivity.java:326) 02-19 15:08:02.228: E/WindowManager(22172): at android.media.MediaPlayer$EventHandler.handleMessage(MediaPlayer.java:2113) 02-19 15:08:02.228: E/WindowManager(22172): at android.os.Handler.dispatchMessage(Handler.java:99) 02-19 15:08:02.228: E/WindowManager(22172): at android.os.Looper.loop(Looper.java:137) 02-19 15:08:02.228: E/WindowManager(22172): at android.app.ActivityThread.main(ActivityThread.java:4881) 02-19 15:08:02.228: E/WindowManager(22172): at java.lang.reflect.Method.invokeNative(Native Method) 02-19 15:08:02.228: E/WindowManager(22172): at java.lang.reflect.Method.invoke(Method.java:511) 02-19 15:08:02.228: E/WindowManager(22172): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:804) 02-19 15:08:02.228: E/WindowManager(22172): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:571) 02-19 15:08:02.228: E/WindowManager(22172): at dalvik.system.NativeStart.main(Native Method)
這是我在播放視頻彈出Dialog時,出現的異常。java
分析:android
常常在應用中須要處理一些耗時的工做,諸如讀取大文件、訪問網絡資源等。爲了不因程序假死而帶來的糟糕用戶體驗,一般咱們能夠經過線程+Handler或者Android提供的AsyncTask來解決該問題,並通常以ProgressDialog等提示性控件來告知用戶當前的程序進度。而標題中描述的異常則會經常出如今這樣的場景中,而且每每掩蓋了致使異常的真正的罪魁禍首。網絡
問題緣由:app
從 異常描述中,大體的意思是存在窗口句柄泄露,即未能及時銷燬某個PhoneWindow。而這每每誤導了咱們,把過多的精力放在查找所謂的內存泄露上了。 其實存在這麼一種狀況,即因咱們在非主線程中的某些操做不當而產生了一個嚴重的異常,從而強制當前Activity被關閉。而在關閉的同時,卻沒能及時的 調用dismiss來解除對ProgressDialog等的引用,從而系統拋出了標題中的錯誤,而掩蓋了真正致使這個錯誤的異常信息。oop
解決方法之一:spa
本解決方法並不能真正的解決問題,可是在必定程度上能夠將真正致使錯誤的異常信息顯露出來。即重寫Activity的onDestroy方法,在方法中調用dismiss來解除對ProgressDialog等的引用。線程
另外引出的一個異常code
Unable to add window -- token android.os.BinderProxy@42f10c40 is not valid; is your activity running?視頻
由於使用了線程,在線程完成之後彈出窗口。
這個時候若是用戶在線程未執行完 按了返回按鈕,activity已經onDestory了,
那麼就會報出android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@4479b390 is not valid; is your activity running?token
解決方法一在彈出窗口以前用Activity的isFinishing判斷一下Activity是否還存在。
if (!Activity.isFinishing() && !dialog.isShowing()) { dialog.show(); }