该文章主要分析Android广播发送的顺序
1、既然分析Broadcast的发送过程,那么先从sendBroadcast(intent)源码为入口。
这里可以直接看(https://my.oschina.net/winHerson/blog/91150) 该博客。从该博客一路跟下来发现以下代码。 ActivityManagerService的方法
private final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, Intent intent, String resolvedType,
IIntentReceiver resultTo, int resultCode, String resultData,
Bundle map, String requiredPermission,
boolean ordered, boolean sticky, int callingPid, int callingUid) {
。。。
}
该方法做了包括不限于以下事情
获得当前intent对应的动态和静态receiver
List receivers = null; //存放当前广播对应的所有静态receiver
List registeredReceivers = null; //存放当前广播对应的所有动态receiver
//每个BroadcastRecord 存放当前intent 和对应的动态receiver
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
receivers, resultTo, resultCode, resultData, map, ordered,
sticky, false);
...
mParallelBroadcasts.add(r); 存放所有无序发送的广播
//每个BroadcastRecord 存放当前intent 和对应的静态receiver
BroadcastRecord r = new BroadcastRecord(intent, callerApp,
callerPackage, callingPid, callingUid, requiredPermission,
receivers, resultTo, resultCode, resultData, map, ordered,
sticky, false);
...
mOrderedBroadcasts.add(r);存放所有有序发送的广播
然后触发
scheduleBroadcastsLocked();//进行广播发送
源码如下
private final void scheduleBroadcastsLocked() {
if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
+ mBroadcastsScheduled);
if (mBroadcastsScheduled) {
return;
}
mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
mBroadcastsScheduled = true;
}
mBroadcastsScheduled 表示是否已经向所有运行的线程发送了一个类型为BROADCAST_INTENT_MSG的消息,从以下源码可以看出
final Handler mHandler = new Handler() {
//public Handler() {
// if (localLOGV) Slog.v(TAG, "Handler started!");
//}
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
if (DEBUG_BROADCAST) Slog.v(
TAG, "Received BROADCAST_INTENT_MSG");
processNextBroadcast(true);
} break;
。。。。
}}
然后 processNextBroadcast(true);处理每个广播发送到对应receiver
private final void processNextBroadcast(boolean fromMsg) {
synchronized(this) {
BroadcastRecord r;
if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
+ mParallelBroadcasts.size() + " broadcasts, "
+ mOrderedBroadcasts.size() + " ordered broadcasts");
updateCpuStats();
if (fromMsg) { //(1)这里为true
mBroadcastsScheduled = false;
}
// First, deliver any non-serialized broadcasts right away.
while (mParallelBroadcasts.size() > 0) { //(2) 这里为true
,因为上面向mParallelBroadcasts添加了数据
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
final int N = r.receivers.size();///(3)这里的r.receivers.就是上面创建BroadcastRecord对象时候传入的registeredReceivers
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
+ r);
for (int i=0; i
Object target = r.receivers.get(i);
if (DEBUG_BROADCAST) Slog.v(TAG,
"Delivering non-ordered to registered "
+ target + ": " + r);
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
//执行这行代码
}
addBroadcastToHistoryLocked(r);
if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
+ r);
}
// Now take care of the next serialized one...
// If we are waiting for a process to come up to handle the next
// broadcast, then do nothing at this point. Just in case, we
// check that the process we're waiting for still exists.
if (mPendingBroadcast != null) {
if (DEBUG_BROADCAST_LIGHT) {
Slog.v(TAG, "processNextBroadcast: waiting for "
+ mPendingBroadcast.curApp);
}
boolean isDead;
synchronized (mPidsSelfLocked) {
isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
}
if (!isDead) {
// It's still alive, so keep waiting
return;
} else {
Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
+ " died before responding to broadcast");
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
do {// mOrderedBroadcasts这里是处理有序队列的,因为上面没有传值,就不分析了
if (mOrderedBroadcasts.size() == 0) {
// No more broadcasts pending, so all done!
scheduleAppGcsLocked();
if (looped) {
// If we had finished the last ordered broadcast, then
// make sure all processes have correct oom and sched
// adjustments.
updateOomAdjLocked();
}
return;
}
。。。。。
}
}
从以上源码可以看出Android是把当前的广播全部分发给每个receiver后,才会开始处理下一条广播。 至于BroadcastReceiver 是如何具体接受广播的可以参考(http://blog.csdn.net/windskier/article/details/7251742)