项目里的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
码农场