注册过程(分析动态注册)
广播注册分为静态注册和动态注册。
静态注册的广播在应用安装时由系统自动完成注册,即由PMS(PackageManagerService)来完成整个注册过程的,其他三大组件也是在应用安装时由PMS解析并注册的。
1. ContextWrapper的registerReceiver方法
ContextWrapper
并没有做实际的工作,将注册过程交给ContextImpl
2. ContextImpl registerReceiver
3. ContextImpl的registerReceiverInternal方法
- 系统从
mPagkageInfo
获取IIntentReceiver
对象 - 采用跨进程方式向AMS发送广播注册的请求
PS:采用
IIntentReceiver
是因为注册的过程是一个进程间通信的过程,而BroadcastReceiver是一个android组件,不能直接跨进程传递,需要通过IIntentReceiver
中转一下。
IIntentReceiver
是一个Binder接口,具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver,ReceiverDispatcher内部保存了BroadcastReceiver和InnerReceiver,接收到广播时,ReceiverDispatcher可以方便调用BroadcastReceiver的onReceiver方法。
4. AMS的registerReceiver
方法
把远程的InnerReceiver
对象以及IntentFilter
对象存储起来,整个广播注册过程完成。
发送接收广播过程(分析普通广播)
通过send发送广播,AMS查找匹配的广播接收者并将广播发送给它们处理。广播发送类型:普通广播、有序广播和粘性广播。
1) ContextWrapper的 sendBroadcast
方法
PS:Context的
sendBroadcast
方法是一个抽象方法
2) ContextImpl的 sendBroadcast
方法
向AMS发起一个异步请求用于发送广播
3) AMS的 broadcastIntent
方法
4) AMS的 broadcastIntentLocked
方法
broadcastIntentLocked内部根据intent-filter查找匹配的广播接收者并经过一系列条件过滤,最终将满足条件的广播接收者添加到BroadcastQueue中,接着BroadcastQueue将广播发送给相应的广播接收者。
系统在android3.1中为Intent添加了两个标记位,用来判断广播是否要对于处于停止状态的应用起作用。
-
FLAG_INCLUDE_STOPPED_PACKAGES(两种标记位共存时,以他为准)
表示包含已经停止的应用,这个时候广播会发送给已经停止的应用。 -
FLAG_EXCLUDE_STOPPED_PACKAGES
表示不包含已经停止的应用,这个时候广播不会发送给已经停止的应用。
Android3.1开始,系统为所有广播默认添加
FLAG_EXCLUDE_STOPPED_PACKAGES
,为了防止广播无意间或者在不必要的时候调起已经停止运行的应用。
一个应用处于停止状态
- 安装后未运行
- 应用被手动或者其他应用强停。
5) BroadcastQueue的 scheduleBroadcastsLocked
方法
并没有立即发送广播,发送了一个BROADCAST_INTENT_MSG
类型的信息,BroadcastQueue
收到消息调用processNextBroadcast
方法
6) BroadcastQueue的 processNextBroadcast
方法
无序广播存储在mParallelBroadcasts
中,系统遍历mParallelBroadcasts并将其中的广播发送给它们所有的接收者,通过deliverToRegisteredReceiverLocked
方法。
7) deliverToRegisteredReceiverLocked
方法
将一个广播发送给一个特定的接收者,内部调用performReceiveLocked
方法来完成具体的发送过程。
8) performReceiveLocked
方法
9) ApplicationThread的 scheduleRegisteredReceiver
方法
10) InnerReceiver的 performReceiver
方法
11) LoadedApk.ReceiverDispatcher
的 performReceive
方法
创建一个 Args
对象并通过mActivityThread
的post方法执行Args中的逻辑,Args实现了 Runnable
接口。
mActivityThread
是一个Handler,其实就是ActivityThread
中的mH,mH的类型就是ActivityThread
的内部类H。
至此BroadcastReceiver的onReceive
方法被执行,应用已经收到广播,同时onReceive方法在广播接收器的主线程中被调用。