源码角度分析BroadcastReceiver
BroadcastReceiver
一般广播的使用,都是先注册,后发送。注册可以分为静态注册和动态注册
动态注册
ContextImpl.registerReceiver
1 |
|
ContextImpl.registerReceiverInternal
1 | private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, |
通过ContextImpl
注册。创建IIntentReceiver
,然后通过ActivityManagerService
注册广播
AMS.registerReceiver
1 | public Intent registerReceiver(IApplicationThread caller, String callerPackage, |
检查是否是sticky broadcast
。搜索已注册的广播,如果不存在,创建并缓存。通过每个广播意图,获取对应的前台广播队列或者后台广播队列。然后将新的广播信息入列
BroadcastQueue.scheduleBroadcastsLocked
1 | public void scheduleBroadcastsLocked() { |
通过Handler
来处理广播消息
BroadcastQueue.processNextBroadcast
1 | final void processNextBroadcast(boolean fromMsg) { |
首先处理所有无序广播,然后处理有序广播。之后调用performReceiveLocked
BroadcastQueue.performReceiveLocked
1 | void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, |
如果app
进程还存在,那么直接通知ApplicationThread
处理消息,以保证广播的顺序。最终都是调用IIntentReceiver
LoadApk.ReceiverDispatcher.InnerReceiver
1 |
|
通过IPC
从AMS
通讯回到LoadedApk
静态注册
在AndroidManifest.xml
中注册广播。广播发出后,会经由PackageManagerService
获取当前进程的所有配置信息,然后会做比对
广播发送
AMS.broadcastIntent
1 | public final int broadcastIntent(IApplicationThread caller, |
校验广播意图
AMS.broadcastIntentLocked
1 | final int broadcastIntentLocked(ProcessRecord callerApp, |
首先处理系统的广播消息。然后将广播消息入队列
BroadCastQueue.processNextBroadcast
1 | final void processNextBroadcast(boolean fromMsg) { |
如果当前进程还在,那么处理当前广播
BroadCastQueue.processCurBroadcastLocked
1 | private final void processCurBroadcastLocked(BroadcastRecord r, |
如果当前进程正在备份,那么忽略广播。更新进程状态,调整优先级。然后通知ApplicationThread
处理广播
ActivityThread.handleReceiver
1 | private void handleReceiver(ReceiverData data) { |
通过反射,创建广播对象,然后调用onReceive