1.问题关键日志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FATAL EXCEPTION: main
Process: com.gxatek.cockpit.launcher, PID: 16450
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.gxatek.cockpit.launcher/com.gxatek.cockpit.launcher.LauncherActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@18b6d70 is not valid; is your activity running?
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2951)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3086)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1816)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6718)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@18b6d70 is not valid; is your activity running?
at android.view.ViewRootImpl.setView(ViewRootImpl.java:798)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:356)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at com.iflytek.autofly.cardlist.window.CardListWindowManager.showCardList(CardListWindowManager.java:108)
at com.gxatek.cockpit.launcher.LauncherActivity.onCreate(LauncherActivity.java:153)
at android.app.Activity.performCreate(Activity.java:7144)
at android.app.Activity.performCreate(Activity.java:7135)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2931)
... 11 more

2.日志分析

1
Unable to start activity ComponentInfo{com.gxatek.cockpit.launcher/com.gxatek.cockpit.launcher.LauncherActivity}: android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@18b6d70 is not valid; is your activity running?

从关键日志中可以看出系统提示PhoneWindow绑定了Activity,然而在向window上addview的时候,发现Activity已经被销毁了。

3.分析代码

找到Launcher代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.iflytek.autofly.cardlist.window;

......

public class CardListWindowManager {

private CardListWindowManager(Context context) {
this.mContext = context;
this.init();
this.initCardList();
}

//Launcher主界面(LauncherActivity)传入context
public static synchronized CardListWindowManager getInstance(Context context) {
if (sInstance == null) {
sInstance = new CardListWindowManager(context);
}
return sInstance;
}

private void init() {
// 绑定mWindowManager和LauncherActivity
this.mWindowManager和 = (WindowManager)this.mContext.getSystemService("window");
}

public void showCardList() {
if (this.mCardListView != null && CARD_STATUS) {
// 在调用addView的时候没有判断LauncherActivity是否已经被销毁
this.mWindowManager.addView(this.mCardListView, this.mCardListParams);
CARD_STATUS = false;
}
}
}

4.问题修复

修复方案有两种,第一种是在addview之前对activity判断是否已经finish了;第二种是phonewindow绑定全局context。

修复后的代码

1
2
3
4
5
6
7
8
9
public void showCardList() {
if (mContext != null && mContext instanceof Activity){
// 判断activity是否已经被销毁
if (!((Activity)mContext).isFinishing() && this.mCardListView != null && CARD_STATUS) {
this.mWindowManager.addView(this.mCardListView, this.mCardListParams);
CARD_STATUS = false;
}
}
}