Android8.0无法接收隐式广播消息


App里有一个自己在Manifest文件里面注册的广播接收器(Receiver),到Android8.0的机器上调试的时候却接收不到消息,一番搜索和研究之后,才发现Android8.0已经对隐式广播做了限制。


版本区别

对于targetSdkVersion26或者以上的App,在Manifest里面注册的Receiver已经受到限制,而用Java代码动态注册的Receiver则不受影响。

targetSdkVersion 在 25或以下的App,其Receiver不受影响,即使在Android8.0以上的机器上运行。

如果targetSdkVersion 在26或者以上,在Manifest注册的Receiver可能无法接收到广播消息,并且会在Logcat里面打印出如下消息:

BroadcastQueue: Background execution not allowed: receiving Intent { act=com.xiaoqiang.try.something.receiver flg=0x2010 (has extras) } to xiaoqiang.com.trysomething/.broadcast.TheReceiver


有哪些影响

首先要了解一个概念。官方文档里提到implicit broadcast,可译为隐式广播,指那些没有指定接收App(即包名)的广播。
- 系统发送的广播毫无疑问都是隐式广播,因此基本上都会受到影响,除了部分受豁免广播之外
- App发送的自定义隐式广播,都会受到影响


为何限制隐式广播

总所周知,在Manifest里面注册的系统广播接收器会被缓存在系统中,即使当App关闭之后,如果有相应的广播发出,应用程序仍然会被唤醒。比如如果有20个App在Manifest里面注册了ACTION_BOOT_COMPLETED的广播接收器监听设备启动,那么当设备启动时,就会有20个应用程序被唤醒并作出相应的动作。而动态注册的广播则跟随组件的生命周期而消存。因此在Manifest里面注册广播接收器的App越多,设备的性能就越容易受到影响,限制隐式广播主要是为了优化系统性能。


如何应对这一限制

分析了受限制的原因之后,就知道该如何应对这一影响了。
- 优先使用动态注册Receiver的方式,能动态注册绝不使用Manifest注册

    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("com.xiaoqiang.try.something.receiver");
    TheReceiver receiver = new TheReceiver();
    registerReceiver(receiver, intentFilter);
  • 如果一定要Manifest注册,那么当发送广播的时候,指定广播接收者的包名,即发送显式广播
    Intent intent = new Intent("com.xiaoqiang.try.something.receiver");
    intent.putExtra("receive","test broadcast");
    intent.setPackage(getPackageName());
    //intent.setComponent(...)
    sendBroadcast(intent);
  • 如果要接收系统广播,而对应的广播在Android8.0中无法被接收,那么只能暂时把App的targetSdkVersion改为25或以下。


参考文章:
1. Android O and the Implicit Broadcast Ban
2. 官方文档

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值