BroacastReceive优先级与ReceiveList
系统广播接收优先级
- 动态注册优先级别最高,其次静态注册
- 在动态注册中,最早动态注册优先级别最高
- 在静态注册中,最早安装的程序,静态注册优先级别最高(注:安装APK会解析manifest.xml,把其加入队列)
- 都是静态注册的情况下,按照字符排列顺序决定谁先收到广播消息
- adb install xxx.apk安装的应用优先级比adb push到其他目录的应用高
- 总体来说:对于接收同一个广播,在相同优先级的情况下,动态注册优先级别高于静态注册。在动态注册中,最早动态注册优先级别最高;在静态注册中,最早安装的程序,静态注册优先级别最高(安装APK会解析manifest.xml,把其加入队列)
参考链接:https://ruanyandong.github.io/2018/10/23/Android%E5%B9%BF%E6%92%AD%E7%9A%84%E9%A1%BA%E5%BA%8F/
获取广播的所有接收者
注册BroadcastReceiver的过程是这样的:Activity调用registerReceiver,然后经过几层内部类接口的调用之后,通过Binder机制与ActivityManagerService通信,而ActivityManagerService里有一个ReceiverList保存着系统所有的BroadcastReceiver。
发送广播的过程是:Activity向ActivityManagerService发送广播,ActivityManagerService查找ReceiverList,通过比对IntentFilter找到所有对应的BroadcastReceiver,根据BroadcastReceiver的优先级进行排序后,扔进广播发送队列里。而后由专门的线程负责投递广播消息。
获取ReceiverList就可以查看到获取系统BroadcastReceiver的列表,根据查看框架源码发ReceiverList是按照优先级顺序排序,这样可以通过ReceiverList来查看注册指定动作的广播优先级。
frameworks\base\services\java\com\android\server\IntentReslover.java,通过debug选项可以打印出最终获得的ReceiverList
1 | public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { |
编写demo可以得到ReceiverList
1 |
|
打开应用顺序:火山→超强→84
锁屏顺序:84→超强→火山
ReceiverList显示结果:
同时我在发出广播时遇到了一个问题,系统受保护广播例如android.intent.action.SCREEN_ON,是不可以由外部应用发出,只能由系统才能发出。
参考链接:获取广播接收者https://bbs.pediy.com/thread-156436.htm
android受限广播机制https://my.oschina.net/easley/blog/270296