项目里的ProgressDialog导致了这么一个IllegalArgumentException异常,原因是在延时线程里调用了ProgressDialog.dismiss,但此时主Activity已经destroy了。于是应用崩溃,我写了一个 SafeProgressDialog 来避免这个问题,主要原理是覆写dismiss方法,在ProgressDialog.dismiss之前判断Activity是否存在。
在看源码之前先看看异常:
12-10 07:33:36.193 3335-3335/com.example.LoadingProgressDialogTest E/AndroidRuntime﹕ FATAL EXCEPTION: main java.lang.IllegalArgumentException: View not attached to window manager at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:383) at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:285) at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:79) at android.app.Dialog.dismissDialog(Dialog.java:323) at android.app.Dialog.dismiss(Dialog.java:306) at com.example.LoadingProgressDialogTest.MyActivity$1.run(MyActivity.java:33) at android.os.Handler.handleCallback(Handler.java:725) at android.os.Handler.dispatchMessage(Handler.java:92) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:5041) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at dalvik.system.NativeStart.main(Native Method)
一段fire bug 代码:
public class MyActivity extends Activity { private ProgressDialog mProgressDialog; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // The code below throws a java.lang.IllegalArgumentException: View not attached to window manager // Which makes your app crashed mProgressDialog = new ProgressDialog(this); // But my SafeProgressDialog will solve this issue // mProgressDialog = new SafeProgressDialog(this); mProgressDialog.show(); new Handler().postDelayed(new Runnable() { @Override public void run() { mProgressDialog.dismiss(); } }, 1000); finish(); } }
我写的SafeProgressDialog ,可以完美地防止IllegalArgumentException:
class SafeProgressDialog extends ProgressDialog { Activity mParentActivity; public SafeProgressDialog(Context context) { super(context); mParentActivity = (Activity) context; } @Override public void dismiss() { if (mParentActivity != null && !mParentActivity.isFinishing()) { super.dismiss(); //调用超类对应方法 } } }
为了方便测试,你可以直接复制下面这段代码来测试我的代码:
package com.hankcs.LoadingProgressDialogTest; import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.os.Bundle; import android.os.Handler; public class MyActivity extends Activity { private ProgressDialog mProgressDialog; /** * Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // The code below throws a java.lang.IllegalArgumentException: View not attached to window manager // Which makes your app crashed // mProgressDialog = new ProgressDialog(this); // But my SafeProgressDialog will solve this issue mProgressDialog = new SafeProgressDialog(this); mProgressDialog.show(); new Handler().postDelayed(new Runnable() { @Override public void run() { mProgressDialog.dismiss(); } }, 1000); finish(); } } class SafeProgressDialog extends ProgressDialog { Activity mParentActivity; public SafeProgressDialog(Context context) { super(context); mParentActivity = (Activity) context; } @Override public void dismiss() { if (mParentActivity != null && !mParentActivity.isFinishing()) { super.dismiss(); //调用超类对应方法 } } }
知识共享署名-非商业性使用-相同方式共享:码农场 » Solution of java.lang.IllegalArgumentException: View not attached to window manager