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

相关文章
相关标签/搜索