|
4 | 4 |
|
5 | 5 | * 博客地址:[只需体验三分钟,你就会跟我一样,爱上这款 Toast](https://www.jianshu.com/p/9b174ee2c571) |
6 | 6 |
|
7 | | -* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/ToastUtils/releases/download/10.2/ToastUtils.apk) |
| 7 | +* 可以扫码下载 Demo 进行演示或者测试,如果扫码下载不了的,[点击此处可直接下载](https://github.com/getActivity/ToastUtils/releases/download/10.3/ToastUtils.apk) |
8 | 8 |
|
9 | 9 |  |
10 | 10 |
|
@@ -47,7 +47,7 @@ android { |
47 | 47 |
|
48 | 48 | dependencies { |
49 | 49 | // 吐司框架:https://github.com/getActivity/ToastUtils |
50 | | - implementation 'com.github.getActivity:ToastUtils:10.2' |
| 50 | + implementation 'com.github.getActivity:ToastUtils:10.3' |
51 | 51 | } |
52 | 52 | ``` |
53 | 53 |
|
@@ -140,7 +140,7 @@ ToastUtils.init(this, new ToastStrategy() { |
140 | 140 |
|
141 | 141 | | 功能或细节 | [ToastUtils](https://github.com/getActivity/ToastUtils) | [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode) | [Toasty](https://github.com/GrenderG/Toasty) | |
142 | 142 | | :----: | :------: | :-----: | :-----: | |
143 | | -| 对应版本 | 10.2 | 1.30.6 | 1.5.0 | |
| 143 | +| 对应版本 | 10.3 | 1.30.6 | 1.5.0 | |
144 | 144 | | issues 数 | [](https://github.com/getActivity/ToastUtils/issues) | [](https://github.com/Blankj/AndroidUtilCode/issues) | [](https://github.com/GrenderG/Toasty/issues) | |
145 | 145 | | **aar 包大小** | 28 KB | 500 KB | 50 KB | |
146 | 146 | | **调用代码定位** | ✅ | ❌ | ❌ | |
@@ -168,7 +168,7 @@ ToastUtils.init(this, new ToastStrategy() { |
168 | 168 |
|
169 | 169 | * 这个问题的出现是因为原生 Toast 的显示要通过 NMS(NotificationManagerService) 才会 addView 到 Window 上面,而在 NMS 中有一个 `static final boolean ENABLE_BLOCKED_TOASTS = true` 的字段,当这个常量值为 true 时,会触发 NMS 对应用通知栏权限的检查,如果没有通知栏权限,那么这个 Toast 将会被 NMS 所拦截,并输出 `Suppressing toast from package` 日志信息,而小米手机没有这个问题是因为它是将 `ENABLE_BLOCKED_TOASTS` 字段值修改成 `false`,所以就不会触发对通知栏权限的检查,另外我为什么会知道有这个事情?因为我曾经和一名 MIUI 工程师一起确认过这个事情。 |
170 | 170 |
|
171 | | -* 框架处理这个问题的方式有两种,先判断当前应用是否处于前台状态,如果是则使用自定义的 WindowManager 代替 Toast 来显示,如果当前应用处于后台状态,则会通过 Hook Toast 中的 INotificationManager 接口,将 enqueueToast 方法传递的包名参数修改成 `android` 来欺骗 NotificationManagerService,因为 NotificationManagerService 已经将 `android` 包名的应用纳入白名单,会自动放行,需要注意的是,这种方式在 Android 10 上面已经失效了,已经被系统纳入反射黑名单,但是好消息是,通过查看和对比 NotificationManagerService 源码发现,这个问题(关闭通知栏权限后无法在前台弹 Toast 的问题)已经在 Android 10.0 的版本上面被修复了,所以框架只在 Android 9.0 及以下版本并且在关闭了通知栏权限的情况下才去 Hook INotificationManager,另外我还找到了官方关于这块的代码提交记录:[Always allow toasts from foreground apps](https://cs.android.com/android/_/android/platform/frameworks/base/+/58b2453ed69197d765c7254241d9966ee49a3efb),大家可以感兴趣可以看看,还有一个问题,如果你想在 Android 10 之后仍然能在后台显示 Toast,请保证应用的通知栏权限处于开启的状态。 |
| 171 | +* 框架处理这个问题的方式有两种,先判断当前应用是否处于前台状态,如果是则使用自定义的 WindowManager 代替 Toast 来显示,如果当前应用处于后台状态,则会通过 Hook Toast 中的 INotificationManager 接口,将 enqueueToast 方法传递的包名参数修改成 `android` 来欺骗 NotificationManagerService,因为 NotificationManagerService 已经将 `android` 包名的应用纳入白名单,会自动放行,需要注意的是,这种方式在 Android 10 上面已经失效了,已经被系统纳入反射黑名单,但是好消息是,通过查看和对比 NotificationManagerService 源码发现,这个问题(关闭通知栏权限后无法在前台弹 Toast 的问题)已经在 Android 10.0 的版本上面被修复了,所以框架只在 Android 9.0 及以下版本并且在关闭了通知栏权限的情况下才去 Hook INotificationManager,另外我还找到了官方关于这块的代码提交记录:[Always allow toasts from foreground apps](https://cs.android.com/android/_/android/platform/frameworks/base/+/58b2453ed69197d765c7254241d9966ee49a3efb),大家可以感兴趣可以看看,还有一个问题,如果你想在 Android 10 之后仍然能在后台显示 Toast,请保证应用的通知栏权限或者悬浮窗权限处于开启的状态。 |
172 | 172 |
|
173 | 173 | #### Android 11 不能在后台显示 Toast 的问题介绍 |
174 | 174 |
|
|
0 commit comments