最近在做项目的时候,越来越多的开发者反馈SDK Dialog的show以及dismiss导致程序crash,出现的问题是传递进来的Activity被finish或者重建(横竖屏切换)了。下面分别对这两种情况说明以及解决办法。
日志信息:
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@42963e08 is not valid; is your activity running?
- 06-03 17:18:14.550: E/AndroidRuntime(12584): at android.view.ViewRootImpl.setView(ViewRootImpl.java:587)
- 06-03 17:18:14.550: E/AndroidRuntime(12584): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:326)
- 06-03 17:18:14.550: E/AndroidRuntime(12584): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:224)
- 06-03 17:18:14.550: E/AndroidRuntime(12584): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:
149)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at android.view.Window$LocalWindowManager.addView(Window.java:
561)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at android.app.Dialog.show(Dialog.java:
293)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.m.onStart(SocialServiceImpl.java:
1451)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.aa.onStart(SocialServiceImpl.java:
2529)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.ab.onStart(SocialServiceImpl.java:
2557)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.c.c(SocialServiceImpl.java:
2594)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.c.doOauthVerify(SocialServiceImpl.java:
2339)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.c.c(SocialServiceImpl.java:
1456)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): at com.umeng.socialize.controller.impl.c.postShare(SocialServiceImpl.java:
1295)
-
06-
03
17:
18:
14.550: E/AndroidRuntime(
12584): …
17 more
解决办法:
在创建Dialog的时候,我们设置该dialog属于某个activity,这样我们根据Activity的状态决定是否显示Dialog.
创建Dialog时设置activity:
"code" class="java" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 26px;">ProgressDialog "font-family: 微软雅黑;">mDialog = new ProgressDialog(this);
"font-family: 微软雅黑;">mDialog.setMessage("test");
mDialog.setCancelable(false);mDialog.setOwnerActivity(this);
显示Dialog的时候做相应地判断:
-
if ( mDialog !=
null ) {
-
Activity activity = mDialog.getOwnerActivity();
-
if ( activity !=
null && !activity.isFinishing() ) {
-
mDialog.show();
-
}
-
}
日志信息:
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): java.lang.IllegalArgumentException: View not attached to window manager
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:
385)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:
287)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:
79)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.app.Dialog.dismissDialog(Dialog.java:
323)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.app.Dialog.dismiss(Dialog.java:
306)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at com.umeng.soexample.MainActivity$1$
1.onComplete(MainActivity.java:
61)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at com.umeng.socialize.qq.controller.impl.UMQQSsoHandler$4.onCancel(UMQQSsoHandler.java:355)
- 06-03 21:03:18.027: E/AndroidRuntime(6197): at com.tencent.jsutil.PackIUiListener$
1.handleMessage(ProGuard:
29)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.os.Handler.dispatchMessage(Handler.java:
99)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.os.Looper.loop(Looper.java:
153)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at android.app.ActivityThread.main(ActivityThread.java:
5297)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at java.lang.reflect.Method.invokeNative(Native Method)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at java.lang.reflect.Method.invoke(Method.java:
511)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:
833)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:
600)
-
06-
03
21:
03:
18.027: E/AndroidRuntime(
6197): at dalvik.system.NativeStart.main(Native Method)
原因:Dialog在dismiss得时候是通过直接从WindowManager remove操作来完成的。当Activity被销毁后,此时的Dialog处于游离状态,在remove的时候会迭代,如果发现此View没有在数组mViews中时讲抛出IllegalArgumentException(“View not attached to window manager”)异常。
解决办法:
创建Dialog的时候设置该Dialog所属的Activity,在dismiss的时候根据此activity的状态来决定是否dismiss此dialog
-
if ( mDialog !=
null && mDialog.isShowing()) {
-
Activity activity = mDialog.getOwnerActivity();
-
if ( activity !=
null && !activity.isFinishing()) {
-
mDialog.dismiss();
-
}
-
}