Android7.1.1对Type Toast的限制

1、现象


目前测试中发现的现象有两种:

  • 在使用Type Toast悬浮窗的同时,使用了Toast,必现崩溃,即使catch 了Throwable也无法解决,但是将悬浮窗addView的代码注释之后则不出现崩溃;
  • 如果只有Type Toast悬浮窗,不会出现崩溃,3.5s后自动消失

关键log如下:

WindowManager$BadTokenException: Unable to add window -- window android.view.ViewRootImpl$W@363f7b1 has already been added

crash log.png

2、原因分析

从查看google的代码发现,在25版本上有这么一个提交:

https://android.googlesource.com/platform/frameworks/base/+/dc24f93

从注解可以大致了解到,google在该版本开始对TYPE TOAST进行管控,防止一个应用的悬浮窗一直悬浮在另一个应用上造成干扰。

commit.png

在windowManager#addView的流程中:

windowManager#addView ->
WindowManagerImpl#addView ->
WindowManagerGlobal#addView ->
ViewRootImpl#setView ->
WindowManagerService#addWindow

在addView中会给window添加上额外的属性(这里每个版本可能会有不同的实现,这里是android7.1.1的实现)

adJustWindowParamsLw.png

手机上mPolicy可以直接查看PhoneWindowManager的代码实现,此时将window的params属性添加了hideTimeoutMilliseconds,值为3500ms,即最多显示3.5s

hideTimeoutMilliseconds.png

WindowManagerService#addWindow中会依据条件判断是否满足重复添加toast的条件,满足则返回ADD_DUPLICATE_ADD

WindowManagerService#addWindow.png

判断当前应用(UID)是否还有Type toast的悬浮窗在展示

canAddToastWindowForUid.png

在ViewRootImpl中拿到这个结果后则抛出异常:

ViewRootImpl#setView.png

在WindowManagerGlobal中捕获并继续抛出

WindowManagerGlobal#addView.png

如果没有重复添加TYPE TOAST,则显示,并设置延迟消息,延迟时间即为params中设置的最长显示时间

add_ok.png

时间到了之后则强制隐藏

window_hide.png

3、解决方案


目前的解决方案就是在Android7.1.1上使用需要申请system alert window权限的系统级悬浮窗,或者是层级较低的TYPE_PHONE悬浮窗。



本文转载自:https://www.jianshu.com/p/1445e330114b

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值