1. 简介
广播作为Android的四大组件之一,能够实现组件之间的通信。广播过程主要就是注册、发送和接收过程。广播使用了设计模式中的观察者模式:基于消息的发布 / 订阅事件模型,消息的生产者发布事件,而使用者订阅感兴趣的事件。因此,广播能够实现组件间的松耦合,即广播的发送者和接收者事先是可以不用知道对方存在的。接下来,我们来研究一下广播的注册、发送和接收过程的源码。
本文源码基于android 27。
2.广播的注册过程
我们都知道,广播的注册分成两种:静态注册和动态注册。静态注册通过在AndroidManifest.xml
中注册广播接收者,应用安装时PackageManagerService
通过解析AndroidManifest.xml
来完成这个过程,由于涉及到PackageManagerService
,这里暂且不表,后面再去分析PackageManagerService
。我们这里来看下动态注册的过程,要实现动态注册需要调用registerReceiver()
方法,其具体实现位于ContextWrapper
类中。
2.1 ContextWrapper的registerReceiver
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
上面的mBase
实际上是ContextImpl
,Context
类是个抽象类,ContextImpl
类是Context
类的具体实现,而ContextWrapper
类是个装饰者的角色,这里涉及了装饰者模式,对装饰者模式有兴趣的可以看下这篇文章:装饰者模式。
mBase
是在Activity
启动时被赋值的,这里就不祥说了。
我们来看下ContextImpl
类的实现:
2.2 ContextImpl的registerReceiver
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext(), 0);
}
最终会调用registerReceiverInternal()
。
2.3 ContextImpl的registerReceiverInternal
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//mPackageInfo的类型为LoadedApk类
//如果mPackageInfo和context都不为空,则从mPackageInfo中获取IIntentReceiver对象
//mPackageInfo.getReceiverDispatcher()最终还是通过LoadedApk.ReceiverDispatcher.getIIntentReceiver()来获取IIntentReceiver对象
//详见下一小节的代码分析
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//如果mPackageInfo或context为空,则新创建一个ReceiverDispatcher对象并获取IIntentReceiver
//IIntentReceiver的具体实现是在LoadedApk.ReceiverDispatcher.InnerReceiver中
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//ActivityManager.getService()获取到的就是AMS,所以最终会调用到AMS的registerReceiver()方法
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
if (intent != null) {
intent.setExtrasClassLoader(getClassLoader());
intent.prepareToEnterProcess();
}
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
从上面的代码可以看到,首先会获取到一个名为rd
的IIntentReceiver
对象。如果mPackageInfo
和context
都不为空,则从mPackageInfo.getReceiverDispatcher()
中获取;否则从LoadedApk.ReceiverDispatcher.InnerReceiver()
中获取。
最后会将这个IIntentReceiver
对象传递到AMS
中去注册。
我们先来看看mPackageInfo.getReceiverDispatcher()
,其具体实现是在LoadedApk
类中:
2.4 LoadedApk的getReceiverDispatcher
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
if (registered) {
map = mReceivers.get(context);
if (map != null) {
rd = map.get(r);
}
}
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
map.put(r, rd);
}
} else {
rd.validate(context, handler);
}
rd