源码分析:广播的动态注册、发送和接收过程

动态注册过程

ContextWrapper#registerReceiver(以下代码基于API26)

动态注册的过程从ContextWrapper的registerReceiver方法开始

1
2
3
4
5
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}

和Activity、Service一样,ContextWrapper没有做任何操作,而是把任务交给了ContextImpl(mBase的实现类型是ContextImpl)来完成。接着看ContextImpl的registerReceiver方法。

ContextImpl#registerReceiver

1
2
3
4
5
6
7
8
9
10
11
@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方法

ContextImpl#registerReceiverInternal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {

IIntentReceiver rd = null;

//广播接收器不为空时,获取IIntentReceiver对象(IIntentReceiver是一个Binder接口)
if (receiver != null) {
if (mPackageInfo != null && context != null) {
//...
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
//...
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}

try {
//通过AMS的registerReceiver方法注册广播
final Intent intent = ActivityManager.getService().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
broadcastPermission, userId, flags);
//...
return intent;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}

为什么需要先将BroadcastReceiver转化为IIntentReceiver?

因为广播的注册过程是一个进程间通信的进程,而BroadcastReceiver是Android的一个组件,不能直接跨进程传递,而IIntentReceiver是一个Binder接口,可以跨进程,所以需要先将BroadcastReceiver转化为IIntentReceiver。

下面看一下IIntentReceiver的获取,无论是哪种情况,最后都是调用LoadedApk.ReceiverDispatcher的getIIntentReceiver方法

LoadedApk.ReceiverDispatcher#getIIntentReceiver

1
2
3
IIntentReceiver getIIntentReceiver() {
return mIIntentReceiver;
}

其中mIIntentReceiver是一个IIntentReceiver.Stub对象

1
final IIntentReceiver.Stub mIIntentReceiver;

mIIntentReceiver是在ReceiverDispatcher的构造方法中初始化的

1
2
3
4
5
6
7
8
9
ReceiverDispatcher(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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {

//...

synchronized (this) {
//...

//获取该receiver(IIntentReceiver对象)对应的ReceiverList
//ReceiverList继承于ArrayList<BroadcastFilter>,是一个存储BroadcastFilter的集合
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());

//若rl为空,则根据receiver创建对应的ReceiverList,并使两者建立映射关系存入HashMap中
if (rl == null) {
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
//...

mRegisteredReceivers.put(receiver.asBinder(), rl);
}
//...

//BroadcastFilter继承于IntentFilter
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
//将该BroadcastFilter添加进ReceiverList中
rl.add(bf);

mReceiverResolver.addFilter(bf);

//...
}
}

其中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
3
Intent intent = new Intent();
intent.setAction("FIRST_RECEIVER");
sendBroadcast(intent); //发送广播

仍然是从ContextWrapper开始,调用其sendBroadcast方法

ContextWrapper#sendBroadcast

1
2
3
4
@Override
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}

依然是交给ContextImpl来处理,调用其sendBroadcast方法

ContextImpl#sendBroadcast

1
2
3
4
5
6
7
8
9
10
11
12
 @Override
public void sendBroadcast(Intent intent) {
//...
try {
intent.prepareToLeaveProcess(this);
//调用AMS的broadcastIntent方法
ActivityManager.getService().broadcastIntent(
mMainThread.getApplicationThread(), intent, resolvedType, null,
Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
getUserId());
} //...
}

ContextImpl也没做什么,它直接调用AMS的broadcastIntent方法

ActivityManagerService#broadcastIntent

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
//...
synchronized(this) {
//...

int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);

//...
return res;
}
}

继续调用broadcastIntentLocked方法

ActivityManagerService#broadcastIntentLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
//...

//添加这个标志后,广播不会发送给已经停止的应用
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

//...

//判断是否有添加FLAG_RECEIVER_REPLACE_PENDING标记位
//这个flag将会将之前的Intent替代掉。加了这个flag,在发送一系列的这样的Intent之后, //中间有些Intent有可能在你还没有来得及处理的时候,就被替代掉了。
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;

//...

if ((receivers != null && receivers.size() > 0)
|| resultTo != null) {
//获取AMS的广播队列
BroadcastQueue queue = broadcastQueueForIntent(intent);
//先将匹配的广播接收器封装成一个BroadcastRecord对象r
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);

//...

final BroadcastRecord oldRecord =
replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
if (oldRecord != null) {
// Replaced, fire the result-to receiver.
//...
} else {
//将BroadcastRecord对象r插入广播队列queue中
queue.enqueueOrderedBroadcastLocked(r);
//在BroadcastRecord中发送广播
queue.scheduleBroadcastsLocked();
}

} //...

return ActivityManager.BROADCAST_SUCCESS;
}

该方法最终将满足条件的广播接收器封装到BroadcastRecord中,并添加到广播队列BroadcastQueue中,通过BroadcastQueue的scheduleBroadcastsLocked方法发送给相应的广播接收器。接下来看一下BroadcastQueue的scheduleBroadcastsLocked方法。

BroadcastQueue#scheduleBroadcastsLocked

1
2
3
4
5
6
7
8
9
10
11
12
  public void scheduleBroadcastsLocked() {
//...

//mBroadcastsScheduled是一个布尔变量,表明是否发送过BROADCAST_INTENT_MSG消息
if (mBroadcastsScheduled) {
return;
}

//发送BROADCAST_INTENT_MSG消息
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}

对BROADCAST_INTENT_MSG消息的处理是

1
2
3
4
case BROADCAST_INTENT_MSG: {
//...
processNextBroadcast(true);
} break;

可以看到,收到BROADCAST_INTENT_MSG消息后,执行processNextBroadcast方法

BroadcastQueue#processNextBroadcast

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 final void processNextBroadcast(boolean fromMsg) {
synchronized(mService) {
BroadcastRecord r;

//...

//如果是从BROADCAST_INTENT_MSG消息而来,重置mBroadcastsScheduled
if (fromMsg) {
mBroadcastsScheduled = false;
}

//发送无序广播,无序广播存储在mParallelBroadcasts中
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);

//...

final int N = r.receivers.size();
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//该方法负责将广播发送给特定的接收器
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);

}
}

可以看到,将广播发送到对应接收器的过程是通过deliverToRegisteredReceiverLocked方法实现的

BroadcastQueue#deliverToRegisteredReceiverLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {

//...

try {
if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
//...
} else {
//通过该方法完成具体的发送过程
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
}
//...
} //...
}

继续看performReceiveLocked方法

BroadcastQueue#performReceiveLocked

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {

if (app != null) {
if (app.thread != null) {
try {
//app.thread的实现是ActivityThread.ApplicationThread
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);

} //...
} //...
} //...
}

接着调用ApplicationThread的scheduleRegisteredReceiver方法

ActivityThread.ApplicationThread#scheduleRegisteredReceiver

1
2
3
4
5
6
7
8
  public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
int resultCode, String dataStr, Bundle extras, boolean ordered,
boolean sticky, int sendingUser, int processState) throws RemoteException {
updateProcessState(processState, false);
//调用InnerReceiver的performReceive方法
receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
sticky, sendingUser);
}

ReceiverDispatcher.InnerReceiver

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;

InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}

@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
final LoadedApk.ReceiverDispatcher rd;
if (intent == null) {
rd = null;
} else {
rd = mDispatcher.get();
}
//...

if (rd != null) {
//调用LoadedApk.ReceiverDispatcher的performReceive方法
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} //...
}
}

继续调用LoadedApk.ReceiverDispatcher的performReceive方法

LoadedApk.ReceiverDispatcher#performReceive

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {

//Args是LoadedApk.ReceiverDispatcher的内部类
final Args args = new Args(intent, resultCode, data, extras, ordered,
sticky, sendingUser);

//...

//mActivityThread是一个Handler对象,指向ActivityThread中的handler对象
if (intent == null || !mActivityThread.post(args.getRunnable())) {
//...
}
}

在post里面执行了Args的getRunnable方法,其实现如下

LoadedApk.ReceiverDispatcher.Args#getRunnable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;

//...

try {
//...

//回调了BoradcastReceiver的onReceive方法
receiver.onReceive(mContext, intent);
} //...
};
}

可以看到,最终在Args抛出的一个Runnable的run方法中回调了BoradcastReceiver的onReceive方法,并且是在广播接收器的主线程中执行的。

至此,普通广播的发送及接收过程分析完毕。

参考

-------------    本文到此结束  感谢您的阅读    -------------
0%