BroadcastReceiver工作过程

BroadcastReceiver工作过程_第1张图片
有点略长,先抚慰一下

注册过程(分析动态注册)

广播注册分为静态注册和动态注册。

静态注册的广播在应用安装时由系统自动完成注册,即由PMS(PackageManagerService)来完成整个注册过程的,其他三大组件也是在应用安装时由PMS解析并注册的。

BroadcastReceiver工作过程_第2张图片
BroadcastReceiver动态注册过程

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查找匹配的广播接收者并将广播发送给它们处理。广播发送类型:普通广播、有序广播和粘性广播。

BroadcastReceiver工作过程_第3张图片
发送接收广播过程

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方法在广播接收器的主线程中被调用。


BroadcastReceiver工作过程_第4张图片
THAT'S ALL

你可能感兴趣的:(BroadcastReceiver工作过程)