早~~,大年初二,一大早就被喉咙痛痛醒(夜晚睡觉之前不要饮太多雪碧),实在受不了,就起床了,想起前段时间在小米系统上遇到的一个诡异问题,于是趁这个机会码一下
问题
某一天发现在小米的MIUI系统上,一个好好的Toast总是不能弹出来,写法是没有问题的,直到发现log中出现一个invisible to user
的输出,几经google,百度,解决方案没找到,倒是在 小米开发者论坛帖子中找到发现相同问题的同学们T_T
问题明确了:后台应用在小米MIUI系统(没有仔细测试每个版本,应该是自某个版本开始的,大概测试的时候,低版本miui还是正常运行,高版本的就不能)上没有办法弹出Toast。
解决
经过一番看源码和在某一篇关于Toast源码分析的博文中了解到
Toast的弹出流程:
- 通过
new Toast(Context context)
或者makeText(...)
方法实例化Toast对象 - 调用
show()
方法之后,实例会加入到一个TN变量(AIDL)的服务队列中,而这个队列由系统维护 - TN控制Toast的显示和消息
于是就好猜测了,MIUI上可能是出于“绿化”的考虑,在维护Toast队列的时候,Toast只能在自己的进程运行在顶端的时候才能弹出来,否则就“invisible to user”.
那么尝试性的解决方案就有了:我们自己参照Toast的源码,重写一份,最后show的时候,不进入TN维护的队列,我们自己用Handler+Queue来维护Toast的消息队列
1 | package io.github.zhitaocai.toastcompat.toastcompat; |
完整源码地址在这里
后记(2016-02-19)
今天测试的时候,升级红米2的MIUI系统为 MIUI 7.0 | 稳定版7.0.6.0 (LHMCNCI) ,发现使用系统默认的toast,后台应用也能弹出toast了
所以猜测MIUI系统在某个版本区间,才会出现后台应用没法弹出toast的问题