1、使用的是Android 7.1.2的源代码:
https://pan.baidu.com/s/1XcVD68cC_2wKtm8jJkdNQA
przv
2、感谢IT先森的系列博客:
Android应用进程创建流程大揭秘
Android四大组件之bindService源码实现详解
Android四大组件之Activity启动流程源码实现详解概要
Activity启动流程(一)发起端进程请求启动目标Activity
Activity启动流程(二)system_server进程处理启动Activity请求
Activity启动流程(三)-Activity Task调度算法复盘分析
Activity启动流程(四)-Pause前台显示Activity,Resume目标Activity
Activity启动流程(五)请求并创建目标Activity进程
Activity启动流程(六)注册目标Activity进程到system_server进程以及创建目标Activity进程Application
Activity启动流程(七)初始化目标Activity并执行相关生命周期流程
一、AMS进程
AMS.attachApplicationLocked 执行完 thread.bindApplication 之后,接着执行6,即检查有没有四大组件等待在该进程中运行,如果有,继续执行四大组件。不过,这里只有Activity、Service和BroadCastReceiver三种组件,ContentProvider的发布会在bindApplication的时候进行。这里我们只关注Activity的启动。
1、AMS.attachApplicationLocked
// [AMS]
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
ProcessRecord app;
long startTime = SystemClock.uptimeMillis();
/*
1、根据PID映射应用进程的ProcessRecord对象
那么此处的ProcessRecord是什么时候创建并加入到mPidsSelfLocked中的呢,这个在该系列博客的五中有详细描述
*/
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;
}
if (app == null) {
//当获取目标Activity进程的ProcessRecord失败,则会执行清理逻辑,并强制退出
// 获取ProcessRecord对象失败,则做一些清理操作后退出
if (pid > 0 && pid != MY_PID) {
Process.killProcessQuiet(pid);
} else {
try {
thread.scheduleExit();
} catch (Exception e) {
}
}
return false;
}
/*
当下需要将ProcessRecord绑定到一个新的进程
所以需要将之前ProcessRecord所绑定的进程信息清除
这个地方有点难理解,我们可以认为对此处的ProcessRecord进行复用,在复用之前需要做一些清理
*/
if (app.thread != null) {
handleAppDiedLocked(app, true, true);
}
final String processName = app.processName;
try {
/*
2、注册应用进程的DeathRecipient,当应用进程崩溃时,系统进程可以收到通知
为啥要整这一套呢,主要是因为AMS服务监听到应用进程奔溃以后需要做一些资源包回收和数据结构的调整
关于AppDeathRecipient可以参见大神gityuan的博客http://gityuan.com/2016/10/03/binder_linktodeath/
*/
AppDeathRecipient adr = new AppDeathRecipient(
app, pid, thread);
thread.asBinder().linkToDeath(adr, 0);
app.deathRecipient = adr;
} catch (RemoteException e) {
app.resetPackageList(mProcessStats);
startProcessLocked(app, "link fail", processName);
return false;
}
//3、激活ProcessRecord对象
//将目标Activity进程的IApplicationThread匿名Binder代理端绑定到ProcessRecord对象
app.makeActive(thread, mProcessStats);
/****************************************************/
//这里为了演示方便,直接给出源码
//[ProcessRecord.java]
final class ProcessRecord {
IApplicationThread thread;
public void makeActive(IApplicationThread _thread, ProcessStatsService tracker) {
if (thread == null) {
...
}
thread = _thread;
}
}
/****************************************************/
//继续进行其它的对ProcessRecord的赋值
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
app.forcingToForeground = null;
updateProcessForegroundLocked(app, false, false);
app.hasShownUi = false;
app.debugging = false;
app.cached = false;
app.killedByAm = false;
app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
//移除进程启动超时消息,就是前面ANR的埋雷机制
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
// 4、获取应用进程的所有Provider
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
//这又是一个ANR埋雷,后续在ContentProvider发布的时候会进行解除
if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
msg.obj = app;
mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
}
...
try {
...
//省略debug和性能优化等相关配置的代码,这里就不赘述了
//5、这里又是老熟人了,一路分析过来见过很多次了,此处发起跨进程调用,将一堆的信息传递给目标Activity应用进程
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode ||