问题描述
日前在做的项目中遇到了一个问题是悬浮窗在弹出时总是出错,系统是Android7.1.1。问题具体错误日志如下:
[16:10:30]01-11 16:10:01.247 W/WindowManager( 448): Attempted to add a toast window with bad token null. Aborting.
[16:10:30]01-11 16:10:01.249 W/System.err( 2948): android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
[16:10:30]01-11 16:10:01.250 W/System.err( 2948): at android.view.ViewRootImpl.setView(ViewRootImpl.java:679)
[16:10:30]01-11 16:10:01.250 W/System.err( 2948): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
[16:10:30]01-11 16:10:01.250 W/System.err( 2948): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
可以看到的问题是在悬浮窗弹出的时候当前依附的activity已经消失了,判定当前的依附的token为null导致的出错。
问题分析
根据上述的错误日志,我们可以很容易的查到报错的位置,在ViewRootImpl
中的setView
方法中,错误位置如下:

可以看到错误是对于res
的判断,我们看下这个res
的赋值,如下:
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(), mWinFrame,
mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
mAttachInfo.mOutsets, mAttachInfo.mDisplayCutout, mInputChannel);
跟踪查询mWindowSession
,可以看到


查看到是通过AIDL返回的WindowManagerService
,继续查看WindowManagerService
。
可以在Session
的addToDisplay
方法里查找到错误:

可以看到下面这句注释:
// Apps targeting SDK above N MR1 cannot arbitrary add toast windows.
提醒我们在target sdkVersion在7.1以上的toast弹窗不能够随意弹出。查看了自己的targetSDKVersion是26,调低至24解决问题。
解决办法
按照注释的说明,降低了自己的targetSDKVersion版本,由26降低至24,问题解决。
总结
对应在build文件中配置的SDKVersion版本我们还是需要去注意的:
- minSdkVersion:用于指定app最低兼容的系统版本,低于此版本的系统将无法安装此app
- targetSdkVersion:通俗的来说就是兼容版本,由于安卓系统会更新,每个版本都会向前兼容。如果当前系统版本高于你的targetSdkVersion,就会去使用兼容方案。当然取较高的版本也可以使用最新的特性。
网友评论