1. binderDied函数分析
**ActvityManagerService.java::AppDeathRecipientbinderDied**
~~~
public void binderDied() {
//注意,该函数也是通过Binder线程调用的,所以此处要加锁
synchronized(ActivityManagerService.this) {
appDiedLocked(mApp, mPid, mAppThread);
}
}
~~~
最终的处理函数是appDiedLocked,其中所传递的3个参数保存了对应死亡进程的信息。来看appDiedLocked的代码::
**ActvityManagerService.java::appDiedLocked**
~~~
final void appDiedLocked(ProcessRecord app, intpid,
IApplicationThread thread) {
......
if(app.pid == pid && app.thread != null &&
app.thread.asBinder() == thread.asBinder()) {
//当内存低到水位线时,LMK模块也会杀死进程。对AMS来说,需要区分进程死亡是LMK导致的
//还是其他原因导致的。App instrumentationClass一般都为空,故此处doLowMem为true
booleandoLowMem = app.instrumentationClass == null;
//①下面这个函数非常重要
handleAppDiedLocked(app, false, true);
if(doLowMem) {
boolean haveBg = false;
//如果系统中还存在oom_adj大于HIDDEN_APP_MIN_ADJ的进程,就表明不是LMK模块因
//内存不够而导致进程死亡的
for(int i=mLruProcesses.size()-1; i>=0; i--) {
ProcessRecord rec = mLruProcesses.get(i);
if (rec.thread != null && rec.setAdj >=
ProcessList.HIDDEN_APP_MIN_ADJ){
haveBg = true;//还有后台进程,故可确定系统内存尚未吃紧
break;
}
}//for循环结束
//如果没有后台进程,表明系统内存已吃紧
if(!haveBg) {
long now = SystemClock.uptimeMillis();
for(int i=mLruProcesses.size()-1; i>=0; i--) {
.....//将这些进程按一定规则加到mProcessesToGc中,尽量保证
//heavy/important/visible/foreground的进程位于mProcessesToGc数组
//的前端
}//for循环结束
/*
发送GC_BACKGROUND_PROCESSES_MSG消息给mHandler,该消息的处理过程就是:
调用应用进程的scheduleLowMemory或processInBackground函数。其中,
scheduleLowMemory将触发onLowMemory回调被调用,而processInBackground将
触发应用进程进行一次垃圾回收
读者可自行阅读该消息的处理函数performAppGcsIfAppropriateLocked
*/
scheduleAppGcsLocked();
}// if(!haveBg)判断结束
}//if(doLowMem)判断结束
}
~~~
以上代码中有一个关键函数handleAppDiedLocked,下面来看它的处理过程。
2. handleAppDiedLocked函数分析
**ActivityManagerService.java::handleAppDiedLocked**
~~~
private final voidhandleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
//①在本例中,传入的参数为restarting=false, allowRestart=true
cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
if(!restarting) {
mLruProcesses.remove(app);
}
......//下面还有一部分代码处理和Activity相关的收尾工作,读者可自行阅读
}
~~~
重点看上边代码中的cleanUpApplicationRecordLocked函数,该函数的主要功能就是处理Service、ContentProvider及BroadcastReceiver相关的收尾工作。先来看Service方面的工作。
(1) cleanUpApplicationRecordLocked之处理Service
**ActivityManagerService.java::cleanUpApplicationRecordLocked**
~~~
privatefinal void cleanUpApplicationRecordLocked(ProcessRecord app,
boolean restarting, boolean allowRestart, int index) {
if (index>= 0) mLruProcesses.remove(index);
mProcessesToGc.remove(app);
//如果该Crash进程有对应打开的对话框,则关闭它们,这些对话框包括crash、anr和wait等
if(app.crashDialog != null) {
app.crashDialog.dismiss();
app.crashDialog = null;
}
......//处理anrDialog、waitDialog
//清理app的一些参数
app.crashing = false;
app.notResponding = false;
......
//处理该进程中所驻留的Service或它和别的进程中的Service建立的Connection关系
//该函数是AMS Service处理流程中很重要的一环,读者要仔细阅读
killServicesLocked(app,allowRestart);
~~~
cleanUpApplicationRecordLocked函数首先处理几个对话框(dialog),然后调用killServicesLocked函数做相关处理。作为Service流程的一部分,读者需要深入研究。
(2) cleanUpApplicationRecordLocked之处理ContentProvider
再来看cleanUpApplicationRecordLocked下一阶段的工作,主要和ContentProvider有关。
**ActivityManagerService.java::cleanUpApplicationRecordLocked**
~~~
booleanrestart = false;
int NL = mLaunchingProviders.size();
if(!app.pubProviders.isEmpty()) {
//得到该进程中发布的ContentProvider信息
Iterator<ContentProviderRecord> it =
app.pubProviders.values().iterator();
while(it.hasNext()) {
ContentProviderRecord cpr = it.next();
cpr.provider = null;
cpr.proc = null;
int i = 0;
if(!app.bad && allowRestart) {
for (; i<NL; i++) {
/*
如果有客户端进程在等待这个已经死亡的ContentProvider,则系统会
尝试重新启动它,即设置restart变量为true
*/
if (mLaunchingProviders.get(i) == cpr) {
restart = true;
break;
}
}//for循环结束
} else i = NL;
if(i >= NL) {
/*
如果没有客户端进程等待这个ContentProvider,则调用下面这个函数处理它,我们
在卷I的第10章曾提过一个问题,即ContentProvider进程被杀死
后,系统该如何处理那些使用了该ContentProvider的客户端进程。例如,Music和
MediaProvider之间有交互,如果杀死了MediaProvider,Music会怎样呢?
答案是系统会杀死Music,证据就在removeDyingProviderLocked函数
中,读者可自行阅读其内部处理流程
*/
removeDyingProviderLocked(app, cpr);
NL = mLaunchingProviders.size();
}
}// while(it.hasNext())循环结束
app.pubProviders.clear();
}
//下面这个函数的功能是检查本进程中的ContentProvider是否存在于
// mLaunchingProviders中,如果存在,则表明有客户端在等待,故需考虑是否重启本进程或者
//杀死客户端(当死亡进程变成bad process的时,需要杀死客户端)
if(checkAppInLaunchingProvidersLocked(app, false)) restart = true;
......
~~~
从以上的描述中可知,ContentProvider所在进程和其客户端进程实际上有着非常紧密而隐晦(之所以说其隐晦,是因为SDK中没有任何说明)的关系。在目前软件开发追求模块间尽量保持松耦合关系的大趋势下,Android中的ContentProvider和其客户端这种紧耦合的设计思路似乎不够明智。不过,这种设计是否是不得已而为之呢?读者不妨探讨一下,如果有更合适的解决方案,期待能一起分享。
(3) cleanUpApplicationRecordLocked之处理BroadcastReceiver
**ActivityManagerService.java::cleanUpApplicationRecordLocked**
~~~
skipCurrentReceiverLocked(app);
//从AMS中去除接收者
if(app.receivers.size() > 0) {
Iterator<ReceiverList> it = app.receivers.iterator();
while(it.hasNext()) {
removeReceiverLocked(it.next());
}
app.receivers.clear();
}
if(mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
//处理Backup信息
}
mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid,
app.info.uid,null).sendToTarget();
//注意该变量名为restarting,前面设置为restart.
if(restarting) return;
if(!app.persistent) {
mProcessNames.remove(app.processName, app.info.uid);
if(mHeavyWeightProcess == app) {
......//处理HeavyWeightProcess
}
} elseif (!app.removed) {
if(mPersistentStartingProcesses.indexOf(app) < 0) {
mPersistentStartingProcesses.add(app);
restart = true;
}
}
mProcessesOnHold.remove(app);
if (app== mHomeProcess) mHomeProcess = null;
if(restart) {//如果需要重启,则调用startProcessLocked处理它
mProcessNames.put(app.processName, app.info.uid, app);
startProcessLocked(app, "restart", app.processName);
} elseif (app.pid > 0 && app.pid != MY_PID) {
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
app.setPid(0);
}
}
~~~
在这段代码中,除了处理BrodcastReceiver方面的工作外,还包括其他方面的收尾工作。最后,如果要重启该应用,则需调用startProcessLocked函数进行处理。这部分代码不再详述,读者可自行阅读。
- 前言
- 第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 本章小结