View not attached to window manager解決方案

前幾日出現這樣一個Bug是一個RuntimeException,詳細信息是這樣子的:
java.lang.IllegalArgumentException: View not attached to window manager
    at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:356)
    at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:201)
    at android.view.Window$LocalWindowManager.removeView(Window.java:400)
    at android.app.Dialog.dismissDialog(Dialog.java:268)
    at android.app.Dialog.access$000(Dialog.java:69)
    at android.app.Dialog$1.run(Dialog.java:103)
    at android.app.Dialog.dismiss(Dialog.java:252)
    at xxx.onPostExecute(xxx$1.java:xxx)
首先是Google了下,發現引起這個的緣由基本上都一致都是Dismiss對話框的時候,Activity已經再也不存在。
java

常發生這類Exception的情形都是,有一個費時的線程操做,須要在顯示一個ProgressDialog,在任務開始的時候顯示一個對話框,而後當任務完成了再Dismiss對話框,若是在此期間若是Activity由於某種緣由被殺掉且又從新啓動了,那麼當Dismiss的時候WindowManager檢查發現Dialog所屬的Activity已經不存在了,因此會報IllegalArgumentException: View not attached to window manager.
其實此類Exception的一重要的緣由是,ProgressDialog的建立顯示和取消都容許在非UI線程中進程。在Android當中非UI線程是不容許操做UI相關的事情,好比添加移除View等,可是爲會麼容許建立顯示和取消對話框呢?並且還有可能引起此Exception致使應用Crash。
要想避免此類Exception,就要正確的使用對話框,也要正確的使用線程。
正確的使用對話框。不要在非UI線程中使用對話框建立,顯示和取消對話框。
那麼對於異步操做顯示對話框怎麼辦呢?Activity都有相應的操做對話框的回調好比onCreateDialog(),showDialog(),dimissDialog(),removeDialog()等等。這些由於都是Activity的方法,因此用起來更方便,也不用顯示建立和操控Dialog對象,一切都由框架操控,相對來講比較安全。
另外就是必定要讓對話框對象在Activity的可控制範圍以內和生命週期以內,好比必定要是它的成員變量,而且在讓對話框變量活躍在Activity的onCreate()和onDestroy()之間。
正確的使用線程 www.2cto.com
儘可能少用單獨線程,除非是真正的費時操做才用線程,線程也不要直接用Java式的匿名線程,除非是那種單純的操做,操做完成後不須要作其餘事情的。
儘量多用Android提供的類好比AsyncTask等。另外若是線程操做過程當中還須要與主線程有交互,那麼最好保存一個線程的對象,而且線程內部最有必定的控制,這樣可讓Activity更好的操控線程。
若是說某些操做是特別費時的,且是常常性的操做,好比從網絡獲取數據,或是從後臺讀取文件,或是導入/導出,恢復/備份的事情,最好放到後臺Service中去作,而後在StatusBar中給出相應進度。
android

一樣的問題還會發生在Dialog 和PopopWindow 的dissmiss過程當中。對應Dialog,Activity提供了統一的方法來管理對象的建立和銷燬等,建議使用此類方法。安全

對於PopopWindow對象,建議子銷燬的時候判斷當前Activity是否被finish。網絡

if(mAcitvity!=null && !mAcitivity.isFinish()){app

        popwindow.dissmiss();框架

}異步

隨便提醒下,可能存在已知或未知的acitvity關閉的地方,比方說,旋轉屏,若是沒作處理,會致使activity重建。spa

相關文章
相關標籤/搜索