动态注册过程
ContextWrapper#registerReceiver(以下代码基于API26)
动态注册的过程从ContextWrapper的registerReceiver方法开始1
2
3
4
5
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
和Activity、Service一样,ContextWrapper没有做任何操作,而是把任务交给了ContextImpl(mBase的实现类型是ContextImpl)来完成。接着看ContextImpl的registerReceiver方法。
ContextImpl#registerReceiver
1 |
|
又调用自己的registerReceiverInternal方法
ContextImpl#registerReceiverInternal
1 | private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, |
为什么需要先将BroadcastReceiver转化为IIntentReceiver?
因为广播的注册过程是一个进程间通信的进程,而BroadcastReceiver是Android的一个组件,不能直接跨进程传递,而IIntentReceiver是一个Binder接口,可以跨进程,所以需要先将BroadcastReceiver转化为IIntentReceiver。
下面看一下IIntentReceiver的获取,无论是哪种情况,最后都是调用LoadedApk.ReceiverDispatcher的getIIntentReceiver方法
LoadedApk.ReceiverDispatcher#getIIntentReceiver
1 | IIntentReceiver getIIntentReceiver() { |
其中mIIntentReceiver是一个IIntentReceiver.Stub对象1
final IIntentReceiver.Stub mIIntentReceiver;
mIIntentReceiver是在ReceiverDispatcher的构造方法中初始化的1
2
3
4
5
6
7
8
9ReceiverDispatcher(BroadcastReceiver receiver, Context context,
Handler activityThread, Instrumentation instrumentation,
boolean registered) {
//...
mIIntentReceiver = new InnerReceiver(this, !registered);
//...
}
可以看到,最终IIntentReceiver的实现类是LoadedApk.ReceiverDispatcher.InnerReceiver
继续看回注册过程:1
2
3
4
5
6//ActivityManager.getService()返回的是ActivityManagerService对象
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
//...
return intent;
可以看到,注册过程的真正实现是AMS的registerReceiver方法
ActivityManagerService#registerReceiver
1 | public Intent registerReceiver(IApplicationThread caller, String callerPackage, |
其中mRegisteredReceivers的定义如下:1
2
3
4
5/**
* Keeps track of all IIntentReceivers that have been registered for broadcasts.
* Hash keys are the receiver IBinder, hash value is a ReceiverList.
*/
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
可以看到,一个IIntentReceiver对应着一个ReceiverList
最终,通过HashMap把IIntentReceiver与对应的ReceiverList保存起来;而ReceiverList又把可以启动该BroadcastReceiver的IntentFilter保存起来。
发送、接收普通广播
以下是一个发送普通广播的例子:1
2
3Intent intent = new Intent();
intent.setAction("FIRST_RECEIVER");
sendBroadcast(intent); //发送广播
仍然是从ContextWrapper开始,调用其sendBroadcast方法
ContextWrapper#sendBroadcast
1 |
|
依然是交给ContextImpl来处理,调用其sendBroadcast方法
ContextImpl#sendBroadcast
1 |
|
ContextImpl也没做什么,它直接调用AMS的broadcastIntent方法
ActivityManagerService#broadcastIntent
1 | public final int broadcastIntent(IApplicationThread caller, |
继续调用broadcastIntentLocked方法
ActivityManagerService#broadcastIntentLocked
1 | final int broadcastIntentLocked(ProcessRecord callerApp, |
该方法最终将满足条件的广播接收器封装到BroadcastRecord中,并添加到广播队列BroadcastQueue中,通过BroadcastQueue的scheduleBroadcastsLocked方法发送给相应的广播接收器。接下来看一下BroadcastQueue的scheduleBroadcastsLocked方法。
BroadcastQueue#scheduleBroadcastsLocked
1 | public void scheduleBroadcastsLocked() { |
对BROADCAST_INTENT_MSG消息的处理是1
2
3
4case BROADCAST_INTENT_MSG: {
//...
processNextBroadcast(true);
} break;
可以看到,收到BROADCAST_INTENT_MSG消息后,执行processNextBroadcast方法
BroadcastQueue#processNextBroadcast
1 | final void processNextBroadcast(boolean fromMsg) { |
可以看到,将广播发送到对应接收器的过程是通过deliverToRegisteredReceiverLocked方法实现的
BroadcastQueue#deliverToRegisteredReceiverLocked
1 | private void deliverToRegisteredReceiverLocked(BroadcastRecord r, |
继续看performReceiveLocked方法
BroadcastQueue#performReceiveLocked
1 | void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, |
接着调用ApplicationThread的scheduleRegisteredReceiver方法
ActivityThread.ApplicationThread#scheduleRegisteredReceiver
1 | public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, |
ReceiverDispatcher.InnerReceiver
1 | final static class InnerReceiver extends IIntentReceiver.Stub { |
继续调用LoadedApk.ReceiverDispatcher的performReceive方法
LoadedApk.ReceiverDispatcher#performReceive
1 | public void performReceive(Intent intent, int resultCode, String data, |
在post里面执行了Args的getRunnable方法,其实现如下
LoadedApk.ReceiverDispatcher.Args#getRunnable
1 | public final Runnable getRunnable() { |
可以看到,最终在Args抛出的一个Runnable的run方法中回调了BoradcastReceiver的onReceive方法,并且是在广播接收器的主线程中执行的。
至此,普通广播的发送及接收过程分析完毕。
参考
- 《Android开发艺术探索》
- BroadcastReceiver源码解析(二)