Android 解析 Unable to add window is your activity running?

错误堆栈:

    Process: com.example.caoxinyu.myapplication, PID: 22745
    android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@2205c13 is not valid; is your activity running?
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:814)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:373)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:95)
        at android.app.Dialog.show(Dialog.java:342)
        at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:1007)
        at com.example.caoxinyu.myapplication.Main2Activity$1.run(Main2Activity.java:24)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6743)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:486)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:882)

复现步骤:

public class Main2Activity extends AppCompatActivity {

    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder builder = new AlertDialog.Builder(Main2Activity.this);
                builder.setTitle("aaaaa");
                builder.setMessage("aaaaa");
                builder.setNegativeButton("fjff",null);
                builder.setPositiveButton("ffffssss",null).show();
            }
        },5000);

    }
}

当我们打开Activity 之后,等5s dailog 显示 的时候,就会直接崩溃,堆栈就是上面的堆栈。

崩溃时候的调试信息如下:

在这里插入图片描述
可以发现,token 是null.

我们看到,其实是同mTokenMap 里面获取的。

在这里插入图片描述

mTokenMap 的key是binder。

在这里插入图片描述

## 那么什么时候 addToken的呢?

增加token

在这里插入图片描述

at com.android.server.wm.DisplayContent.addWindowToken(DisplayContent.java:845)
	  at com.android.server.wm.DisplayContent.reParentWindowToken(DisplayContent.java:886)
	  at com.android.server.wm.WindowToken.onDisplayChanged(WindowToken.java:270)
	  at com.android.server.wm.WindowToken.<init>(WindowToken.java:124)
	  at com.android.server.wm.WindowToken.<init>(WindowToken.java:112)
	  at com.android.server.wm.AppWindowToken.<init>(AppWindowToken.java:290)
	  at com.android.server.wm.AppWindowToken.<init>(AppWindowToken.java:272)
	  at com.android.server.wm.AppWindowContainerController.createAppWindow(AppWindowContainerController.java:246)
	  at com.android.server.wm.AppWindowContainerController.<init>(AppWindowContainerController.java:230)
	  - locked <0x3d36> (a com.android.server.wm.WindowHashMap)
	  at com.android.server.wm.AppWindowContainerController.<init>(AppWindowContainerController.java:200)
	  at com.android.server.am.ActivityRecord.createWindowContainer(ActivityRecord.java:1012)
	  at com.android.server.am.ActivityStack.startActivityLocked(ActivityStack.java:2925)
	  at com.android.server.am.ActivityStarter.startActivityUnchecked(ActivityStarter.java:1496)
	  at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:1257)
	  at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:879)
	  at com.android.server.am.ActivityStarter.startActivity(ActivityStarter.java:551)
	  at com.android.server.am.ActivityStarter.startActivityMayWait(ActivityStarter.java:1156)
	  - locked <0x3921> (a com.android.server.am.ActivityManagerService)
	  at com.android.server.am.ActivityStarter.execute(ActivityStarter.java:490)
	  at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5109)
	  at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:5083)
	  at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:5074)
	  at android.app.IActivityManager$Stub.onTransact$startActivity$(IActivityManager.java:13759)
	  at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2681)
	  at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3282)
	  at android.os.Binder.execTransact(Binder.java:740)

我们看到当activity 启动的时候,就会去把token 放到map 里面。

移除token:

在这里插入图片描述

	  at com.android.server.wm.DisplayContent.removeWindowToken(DisplayContent.java:866)
	  at com.android.server.wm.DisplayContent.removeAppToken(DisplayContent.java:890)
	  at com.android.server.wm.AppWindowContainerController.removeContainer(AppWindowContainerController.java:260)
	  - locked <0x3d36> (a com.android.server.wm.WindowHashMap)
	  at com.android.server.am.ActivityRecord.removeWindowContainer(ActivityRecord.java:1032)
	  at com.android.server.am.ActivityStack.removeActivityFromHistoryLocked(ActivityStack.java:4123)
	  at com.android.server.am.ActivityStack.activityDestroyedLocked(ActivityStack.java:4406)
	  at com.android.server.am.ActivityStack.activityDestroyedLocked(ActivityStack.java:4386)
	  at com.android.server.am.ActivityManagerService.activityDestroyed(ActivityManagerService.java:8070)
	  - locked <0x3921> (a com.android.server.am.ActivityManagerService)
	  at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:3347)
	  at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3282)
	  at android.os.Binder.execTransact(Binder.java:740)

我们看到当activity destory 的时候,就会去把token 从map 里面移除掉。

如果你在activity onDestory 之后,还用这个activity 去显示了弹窗,那么就会挂掉。

当然当app 挂掉的时候,也会移除token

在这里插入图片描述

	  at com.android.server.wm.DisplayContent.removeWindowToken(DisplayContent.java:866)
	  at com.android.server.wm.WindowToken.removeImmediately(WindowToken.java:262)
	  at com.android.server.wm.AppWindowToken.removeImmediately(AppWindowToken.java:602)
	  at com.android.server.wm.AppWindowToken.removeIfPossible(AppWindowToken.java:609)
	  at com.android.server.wm.AppWindowToken.onRemovedFromDisplay(AppWindowToken.java:674)
	  at com.android.server.wm.DisplayContent.removeAppToken(DisplayContent.java:903)
	  at com.android.server.wm.AppWindowContainerController.removeContainer(AppWindowContainerController.java:260)
	  - locked <0x3d36> (a com.android.server.wm.WindowHashMap)
	  at com.android.server.am.ActivityRecord.removeWindowContainer(ActivityRecord.java:1032)
	  at com.android.server.am.ActivityStack.removeActivityFromHistoryLocked(ActivityStack.java:4123)
	  at com.android.server.am.ActivityStack.removeHistoryRecordsForAppLocked(ActivityStack.java:4516)
	  at com.android.server.am.ActivityStack.handleAppDiedLocked(ActivityStack.java:5006)
	  at com.android.server.am.ActivityStackSupervisor.handleAppDiedLocked(ActivityStackSupervisor.java:2124)
	  at com.android.server.am.ActivityManagerService.handleAppDiedLocked(ActivityManagerService.java:5895)
	  at com.android.server.am.ActivityManagerService.appDiedLocked(ActivityManagerService.java:6076)
	  at com.android.server.am.ActivityManagerService$AppDeathRecipient.binderDied(ActivityManagerService.java:1897)
	  - locked <0x3921> (a com.android.server.am.ActivityManagerService)
	  at android.os.BinderProxy.sendDeathNotice(BinderProxy.java:579)

解决方法:

        if (getActivity().isFinishing()  || getActivity().isDestroyed()) {
            return;
        }

判断activity 的状态,如果是finishing 或者是已经销毁了,那就不要再弹弹窗了。

发布了471 篇原创文章 · 获赞 60 · 访问量 41万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览