BROADCAST_INTENT_MSG消息将触发processNextBroadcast函数,下面分阶段来分析它。
1. processNextBroadcast分析之一
**ActivityManagerService.java::processNextBroadcast**
~~~
private final void processNextBroadcast(booleanfromMsg) {
//如果是BROADCAST_INTENT_MSG消息触发该函数,则fromMsg为true
synchronized(this) {
BroadcastRecord r;
updateCpuStats();//更新CPU使用情况
if(fromMsg) mBroadcastsScheduled = false;
//先处理mParallelBroadcasts中的成员。如前所述,AMS在一个循环中处理它们
while(mParallelBroadcasts.size() > 0) {
r =mParallelBroadcasts.remove(0);
r.dispatchTime =SystemClock.uptimeMillis();
r.dispatchClockTime =System.currentTimeMillis();
final int N = r.receivers.size();
for(int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//①mParallelBroadcasts中的成员全为BroadcastFilter类型,所以下面的函数
//将target直接转换成BroadcastFilter类型。注意,最后一个参数为false
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target,
false);
}
//将这条处理过的记录保存到mHistoryBroadcast中,供调试使用
addBroadcastToHistoryLocked(r);
}
~~~
deliverToRegisteredReceiverLocked函数的功能就是派发广播给接收者,其代码如下:
**ActivityManagerService.java::deliverToRegisteredReceiverLocked**
~~~
private final voiddeliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, booleanordered) {
booleanskip = false;
//检查发送进程是否有filter要求的权限
if(filter.requiredPermission != null) {
intperm = checkComponentPermission(filter.requiredPermission,
r.callingPid, r.callingUid, -1, true);
if(perm != PackageManager.PERMISSION_GRANTED) skip = true;
}
//检查接收者是否有发送者要求的权限
if(r.requiredPermission != null) {
intperm = checkComponentPermission(r.requiredPermission,
filter.receiverList.pid, filter.receiverList.uid, -1, true);
if(perm != PackageManager.PERMISSION_GRANTED) skip = true;
}
if(!skip) {
if(ordered) {
......//设置一些状态,成员变量等信息,不涉及广播发送
}
try {
//发送广播
performReceiveLocked(filter.receiverList.app,
filter.receiverList.receiver,new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, r.ordered, r.initialSticky);
if(ordered) r.state = BroadcastRecord.CALL_DONE_RECEIVE;
}......
}
}
}
~~~
来看performReceiveLocked函数,其代码如下:
**ActivityManagerService.java::performReceiveLocked**
~~~
static void performReceiveLocked(ProcessRecordapp, IIntentReceiver receiver,
Intentintent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky) throws RemoteException {
if(app != null && app.thread != null) {
//如果app及app.thread不为null,则调度scheduleRegisteredReceiver,
//注意这个函数名为scheduleRegisteredReceiver,它只针对动态注册的广播接收者
app.thread.scheduleRegisteredReceiver(receiver,intent, resultCode,
data, extras, ordered, sticky);
} else{
//否则调用IIntentReceiver的performReceive函数
receiver.performReceive(intent, resultCode, data, extras,
ordered, sticky);
}
}
~~~
对于动态注册者而言,在大部分情况下会执行if分支,所以应用进程ApplicationThread的scheduleRegisteredReceiver函数将被调用。稍后再分析应用进程的广播处理流程。
2. processNextBroadcast分析之二
至此,processNextBroadcast已经在一个while循环中处理完mParallelBroadcasts的所有成员了,实际上,这种处理方式也会造成惊群效应,但影响相对较少。这是因为对于动态注册者来说,它们所在的应用进程已经创建并初始化成功。此处的广播发送只是调用应用进程的一个函数而已。相比于创建进程,再初始化Android运行环境所需的工作量,调用scheduleRegisteredReceiver的工作就比较轻松了。
来看processNextBroadcast第二阶段的工作,代码如下:
**ActivityManagerService.java::processNextBroadcast**
~~~
/*
现在要处理mOrderedBroadcasts中的成员。如前所述,它要处理一个接一个的接受者,如果
接收者所在进程还未启动,则需要等待。mPendingBroadcast变量用于标识因为应用进程还未
启动而处于等待状态的BroadcastRecord。
*/
if(mPendingBroadcast != null) {
boolean isDead;
synchronized (mPidsSelfLocked) {
isDead= (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
}
/*重要说明
判断要等待的进程是否为dead进程,如果没有dead进程,则继续等待。仔细思考,此处直接
返回会有什么问题。
问题不小!假设有两个ordered广播A和B,有两个接收者,AR和BR,并且BR所
在进程已经启动并完成初始化Android运行环境。如果processNextBroadcast先处理A,
再处理B,那么此处B的处理将因为mPendingBroadcast不为空而被延后。虽然B和A
之间没有任何关系(例如完全是两个不同的广播消息),
但是事实上,大多数开发人员理解的order是针对单个广播的,例如A有5个接收者,那么对这
5个接收者的广播的处理是串行的。通过此处的代码发现,系统竟然串行处理A和B广播,即
B广播要待到A的5个接收者都处理完了才能处理。
*/
if(!isDead) return;
else {
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
do {
// mOrderedBroadcasts处理完毕
if (mOrderedBroadcasts.size() == 0) {
scheduleAppGcsLocked();
if (looped) updateOomAdjLocked();
return;
}
r =mOrderedBroadcasts.get(0);
boolean forceReceive = false;
//下面这段代码用于判断此条广播是否处理时间过长
//先得到该条广播的所有接收者
intnumReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if(mProcessesReady && r.dispatchTime > 0) {
long now = SystemClock.uptimeMillis();
//如果总耗时超过2倍的接收者个数*每个接收者最长处理时间(10秒),则
//强制结束这条广播的处理
if ((numReceivers > 0) &&
(now > r.dispatchTime +
(2*BROADCAST_TIMEOUT*numReceivers))){
broadcastTimeoutLocked(false);//读者阅读完本节后可自行研究该函数
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}//if(mProcessesReady...)判断结束
if (r.state != BroadcastRecord.IDLE) return;
//如果下面这个if条件满足,则表示该条广播要么已经全部被处理,要么被中途取消
if(r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
if(r.resultTo != null) {
try {
//将该广播的处理结果传给设置了resultTo的接收者
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false);
r.resultTo = null;
}......
}
cancelBroadcastTimeoutLocked();
addBroadcastToHistoryLocked(r);
mOrderedBroadcasts.remove(0);
r = null;
looped = true;
continue;
}
} while (r== null);
~~~
processNextBroadcast第二阶段的工作比较简单:
- 首先根据是否处于pending状态(mPendingBroadcast不为null)进行相关操作。读者要认真体会代码中的重要说明。
- 处理超时的广播记录。这个超时时间是2*BROADCAST_TIMEOUT*numReceivers。BROADCAST_TIMEOUT默认为10秒。由于涉及创建进程,初始化Android运行环境等重体力活,故此处超时时间还乘以一个固定倍数2。
3. processNextBroadcast分析之三
来看processNextBroadcast第三阶段的工作,代码如下:
**ActivityManagerService.java::processNextBroadcast**
~~~
int recIdx= r.nextReceiver++;
r.receiverTime = SystemClock.uptimeMillis();
if (recIdx== 0) {
r.dispatchTime = r.receiverTime;//记录本广播第一次处理开始的时间
r.dispatchClockTime= System.currentTimeMillis();
}
//设置广播处理超时时间,BROADCAST_TIMEOUT为10秒
if (!mPendingBroadcastTimeoutMessage) {
longtimeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
setBroadcastTimeoutLocked(timeoutTime);
}
//取该条广播下一个接收者
ObjectnextReceiver = r.receivers.get(recIdx);
if(nextReceiver instanceof BroadcastFilter) {
//如果是动态接收者,则直接调用deliverToRegisteredReceiverLocked处理
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
deliverToRegisteredReceiverLocked(r, filter, r.ordered);
if(r.receiver == null || !r.ordered) {
r.state = BroadcastRecord.IDLE;
scheduleBroadcastsLocked();
}
return;//已经通知一个接收者去处理该广播,需要等它的处理结果,所以此处直接返回
}
//如果是静态接收者,则它的真实类型是ResolveInfo
ResolveInfo info = (ResolveInfo)nextReceiver;
booleanskip = false;
//检查权限
int perm =checkComponentPermission(info.activityInfo.permission,
r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
info.activityInfo.exported);
if (perm!= PackageManager.PERMISSION_GRANTED) skip = true;
if(info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
r.requiredPermission != null) {
......
}
//设置skip为true
if(r.curApp != null && r.curApp.crashing) skip = true;
if (skip){
r.receiver = null;
r.curFilter = null;
r.state = BroadcastRecord.IDLE;
scheduleBroadcastsLocked();//再调度一次广播处理
return;
}
r.state= BroadcastRecord.APP_RECEIVE;
StringtargetProcess = info.activityInfo.processName;
r.curComponent = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
r.curReceiver = info.activityInfo;
try {
//设置Package stopped的状态为false
AppGlobals.getPackageManager().setPackageStoppedState(
r.curComponent.getPackageName(),false);
} ......
ProcessRecord app = getProcessRecordLocked(targetProcess,
info.activityInfo.applicationInfo.uid);
//如果该接收者对应的进程已经存在
if (app!= null && app.thread != null) {
try {
app.addPackage(info.activityInfo.packageName);
//该函数内部调用应用进程的scheduleReceiver函数,读者可自行分析
processCurBroadcastLocked(r, app);
return;//已经触发该接收者处理本广播,需要等待处理结果
}......
}
//最糟的情况就是该进程还没有启动
if((r.curApp=startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,......)!= 0)) == null) {
......//进程启动失败的处理
return;
}
mPendingBroadcast = r; //设置mPendingBroadcast
mPendingBroadcastRecvIndex = recIdx;
}
~~~
对processNextBroadcast第三阶段的工作总结如下:
- 如果广播接收者为动态注册对象,则直接调用deliverToRegisteredReceiverLocked处理它。
- 如果广播接收者为静态注册对象,并且该对象对应的进程已经存在,则调用processCurBroadcastLocked处理它。
- 如果广播接收者为静态注册对象,并且该对象对应的进程还不存在,则需要创建该进程。这是最糟糕的情况。
此处,不再讨论新进程创建及Android运行环境初始化相关的逻辑,读者可返回阅读“attachApplicationLocked分析之三”,其中有处理mPendingBroadcast的内容。
- 前言
- 第1章 搭建Android源码工作环境
- 1.1 Android系统架构
- 1.2 搭建开发环境
- 1.2.1 下载源码
- 1.2.2 编译源码
- 1.2.3 利用Eclipse调试system_process
- 1.3 本章小结
- 第2章 深入理解Java Binder和MessageQueue
- 2.1 概述
- 2.2 Java层中的Binder架构分析
- 2.2.1 Binder架构总览
- 2.2.2 初始化Java层Binder框架
- 2.2.3 addService实例分析
- 2.2.4 Java层Binder架构总结
- 2.3 心系两界的MessageQueue
- 2.3.1 MessageQueue的创建
- 2.3.2 提取消息
- 2.3.3 nativePollOnce函数分析
- 2.3.4 MessageQueue总结
- 2.4 本章小结
- 第3章 深入理解SystemServer
- 3.1 概述
- 3.2 SystemServer分析
- 3.2.1 main函数分析
- 3.2.2 Service群英会
- 3.3 EntropyService分析
- 3.4 DropBoxManagerService分析
- 3.4.1 DBMS构造函数分析
- 3.4.2 dropbox日志文件的添加
- 3.4.3 DBMS和settings数据库
- 3.5 DiskStatsService和DeviceStorageMonitorService分析
- 3.5.1 DiskStatsService分析
- 3.5.2 DeviceStorageManagerService分析
- 3.6 SamplingProfilerService分析
- 3.6.1 SamplingProfilerService构造函数分析
- 3.6.2 SamplingProfilerIntegration分析
- 3.7 ClipboardService分析
- 3.7.1 复制数据到剪贴板
- 3.7.2 从剪切板粘贴数据
- 3.7.3 CBS中的权限管理
- 3.8 本章小结
- 第4章 深入理解PackageManagerService
- 4.1 概述
- 4.2 初识PackageManagerService
- 4.3 PKMS的main函数分析
- 4.3.1 构造函数分析之前期准备工作
- 4.3.2 构造函数分析之扫描Package
- 4.3.3 构造函数分析之扫尾工作
- 4.3.4 PKMS构造函数总结
- 4.4 APK Installation分析
- 4.4.1 adb install分析
- 4.4.2 pm分析
- 4.4.3 installPackageWithVerification函数分析
- 4.4.4 APK 安装流程总结
- 4.4.5 Verification介绍
- 4.5 queryIntentActivities分析
- 4.5.1 Intent及IntentFilter介绍
- 4.5.2 Activity信息的管理
- 4.5.3 Intent 匹配查询分析
- 4.5.4 queryIntentActivities总结
- 4.6 installd及UserManager介绍
- 4.6.1 installd介绍
- 4.6.2 UserManager介绍
- 4.7 本章学习指导
- 4.8 本章小结
- 第5章 深入理解PowerManagerService
- 5.1 概述
- 5.2 初识PowerManagerService
- 5.2.1 PMS构造函数分析
- 5.2.2 init分析
- 5.2.3 systemReady分析
- 5.2.4 BootComplete处理
- 5.2.5 初识PowerManagerService总结
- 5.3 PMS WakeLock分析
- 5.3.1 WakeLock客户端分析
- 5.3.2 PMS acquireWakeLock分析
- 5.3.3 Power类及LightService类介绍
- 5.3.4 WakeLock总结
- 5.4 userActivity及Power按键处理分析
- 5.4.1 userActivity分析
- 5.4.2 Power按键处理分析
- 5.5 BatteryService及BatteryStatsService分析
- 5.5.1 BatteryService分析
- 5.5.2 BatteryStatsService分析
- 5.5.3 BatteryService及BatteryStatsService总结
- 5.6 本章学习指导
- 5.7 本章小结
- 第6章 深入理解ActivityManagerService
- 6.1 概述
- 6.2 初识ActivityManagerService
- 6.2.1 ActivityManagerService的main函数分析
- 6.2.2 AMS的 setSystemProcess分析
- 6.2.3 AMS的 installSystemProviders函数分析
- 6.2.4 AMS的 systemReady分析
- 6.2.5 初识ActivityManagerService总结
- 6.3 startActivity分析
- 6.3.1 从am说起
- 6.3.2 AMS的startActivityAndWait函数分析
- 6.3.3 startActivityLocked分析
- 6.4 Broadcast和BroadcastReceiver分析
- 6.4.1 registerReceiver流程分析
- 6.4.2 sendBroadcast流程分析
- 6.4.3 BROADCAST_INTENT_MSG消息处理函数
- 6.4.4 应用进程处理广播分析
- 6.4.5 广播处理总结
- 6.5 startService之按图索骥
- 6.5.1 Service知识介绍
- 6.5.2 startService流程图
- 6.6 AMS中的进程管理
- 6.6.1 Linux进程管理介绍
- 6.6.2 关于Android中的进程管理的介绍
- 6.6.3 AMS进程管理函数分析
- 6.6.4 AMS进程管理总结
- 6.7 App的 Crash处理
- 6.7.1 应用进程的Crash处理
- 6.7.2 AMS的handleApplicationCrash分析
- 6.7.3 AppDeathRecipient binderDied分析
- 6.7.4 App的Crash处理总结
- 6.8 本章学习指导
- 6.9 本章小结
- 第7章 深入理解ContentProvider
- 7.1 概述
- 7.2 MediaProvider的启动及创建
- 7.2.1 Context的getContentResolver函数分析
- 7.2.2 MediaStore.Image.Media的query函数分析
- 7.2.3 MediaProvider的启动及创建总结
- 7.3 SQLite创建数据库分析
- 7.3.1 SQLite及SQLiteDatabase家族
- 7.3.2 MediaProvider创建数据库分析
- 7.3.3 SQLiteDatabase创建数据库的分析总结
- 7.4 Cursor 的query函数的实现分析
- 7.4.1 提取query关键点
- 7.4.2 MediaProvider 的query分析
- 7.4.3 query关键点分析
- 7.4.4 Cursor query实现分析总结
- 7.5 Cursor close函数实现分析
- 7.5.1 客户端close的分析
- 7.5.2 服务端close的分析
- 7.5.3 finalize函数分析
- 7.5.4 Cursor close函数总结
- 7.6 ContentResolver openAssetFileDescriptor函数分析
- 7.6.1 openAssetFileDescriptor之客户端调用分析
- 7.6.2 ContentProvider的 openTypedAssetFile函数分析
- 7.6.3 跨进程传递文件描述符的探讨
- 7.6.4 openAssetFileDescriptor函数分析总结
- 7.7 本章学习指导
- 7.8 本章小结
- 第8章 深入理解ContentService和AccountManagerService
- 8.1 概述
- 8.2 数据更新通知机制分析
- 8.2.1 初识ContentService
- 8.2.2 ContentResovler 的registerContentObserver分析
- 8.2.3 ContentResolver的 notifyChange分析
- 8.2.4 数据更新通知机制总结和深入探讨
- 8.3 AccountManagerService分析
- 8.3.1 初识AccountManagerService
- 8.3.2 AccountManager addAccount分析
- 8.3.3 AccountManagerService的分析总结
- 8.4 数据同步管理SyncManager分析
- 8.4.1 初识SyncManager
- 8.4.2 ContentResolver 的requestSync分析
- 8.4.3 数据同步管理SyncManager分析总结
- 8.5 本章学习指导
- 8.6 本章小结