广播的动态注册过程
1 ContextWrapper的registerReceiver方法开始,但并没有真正实现
2 具体实现是在ContextImpl的registerReceiver方法中,该方法调用该类的registerReceiverInternal方法
3 在registerReceiverInternal方法中,调用getReceiverDispatcher方法重新创建了一个ReceiverDispatcher对象,并将其保存的InnerReceriver对象作为返回值返回,其中InnerReceiver对象和BroadcastReceiver都是在ReceiverDispatcher的构造方法中被保存起来的
注册广播的真正核心代码是registerReceiverInternal方法的ActivityManager.getService().registerReceiver(…),ActivityManager.getSerevice()即AMS,具体代码是AMS的registerReceiver方法
4 AMS的registerReceiver关键码:
mRegisteredReceivers.put(receiver.asBinder(), rl);
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,permission, callingUid, userId, instantApp, visibleToInstantApps);
rl.add(bf);
mReceiverResolver.addFilter(bf);
即把远程的InnerReceiver对象以及IntentFilter对象存储起来
以上四个步骤就完成了整个广播的注册过程
广播的发送和接收
当通过send方法来发送广播杀死,AMS会查找出匹配的广播接收者并将广播发送给它们处理
1 广播的发送开始与ContextWrapper的sendBroadcast方法,该方法什么也不做,直接交给ContextImpl去处理
2 ContextImpl的sendBroadcast方法,该方法中向AMS发起了一个异步请求用于发送广播,即具体逻辑是看AMS的broadcastIntent方法
3 AMS的broadcastIntent方法中,调用AMS的broadcastIntentLocked方法
4 在AMW的broadcastIntentLocked内部,会根据intent-filter查找到匹配的广播接收者并经过一系列的条件过滤,最终会将满足条件的广播接受者添加到BroadcastQueue中,接着BroadcastQueue就会将广播发送给相应的广播接收者
5 接着是BroadcastQueue的scheduleBroadcastsLocked方法,该方法并没有立即发送广播,而是发送了一个BROADCAST_INTENT_MSG类型的消息,BroadcastQueue收到消息后会调用processNextBroadcast方法
6 在BroadcastQueue的processNextBroadcast方法中,系统会遍历mParallelBroadcasts(存储无序广播)并将其中的广播发送给它们所有的接收者,具体的发送过程是通过deliverToRegesteredReceiverLocked方法实现的
7 deliverToRegisterdReceiverLocked方法负责将一个广播发送给一个特定的接受者,它的内部调用了performReceiveLocked方法来完成具体的发送过程
8 performReceiveLocked方法中,app.thread(ApplicationThread)调用scheduleRegisteredReceiver方法
9 在app.thread.scheduleRegisteredReceiver方法中,会通过InnnerReceiver调用performReceive方法;而InnerReceiver的performReceive方法会调用LoadedApk.ReceiverDispatcher的performReceive方法
10 在LoadedApk.ReceiverDispatcher的performReceive方法中,会创建一个Args对象并通过mAchtivityThread的post方法来执行Args中的逻辑,而Args实现了Runnable接口。mActivityThread是一个Handler,它其实就是ActivityThread中的mH,mH的类型是ActivityThread的内部类H
11 Args的run方法中通过BroadcastReceiver调用onReceive方法,即此时BroadcastReceiver的onReceive方法被执行,应用已经接受到广播了