ActivityManagerService分析(二)——Activity管理
本文也发布于本人的知乎文章:https://zhuanlan.zhihu.com/p/394199281
(注:源代码为android-8.1)
0. 前言
在文章《Android源码阅读分析:ActivityManagerService分析(一)——启动流程》中,分析了ActivityManagerService
是如何被创建并启动的,以及启动后的初始化操作。前文提到了,ActivityManagerService
是管理四大组件的核心。那么,本篇文章就先从ActivityManagerService
管理Activity
的逻辑开始分析。
1. 启动Activity
这个过程我在文章《Android源码阅读分析:ActivityManagerService分析(一)——启动流程》中已经做了一些简要的代码跟踪分析。这里再详细的分析一下执行启动Activity
的操作的时候,ActivityManagerService
到底做了什么。因为前文已经对方法调用流程做了跟踪,那么本篇文章就针对核心方法来做分析。
首先分析ActivityStarter.startActivity
方法。
(frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java)
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
ActivityRecord[] outActivity, TaskRecord inTask) {
int err = ActivityManager.START_SUCCESS;
...
ProcessRecord callerApp = null;
if (caller != null) {
callerApp = mService.getRecordForAppLocked(caller);
// 可能会出现因内存不足等原因,导致发起者的进程被杀死
if (callerApp != null) {
callingPid = callerApp.pid;
callingUid = callerApp.info.uid;
} else {
// 如果进程被杀死,那么不能启动新的Activity,返回权限拒绝
err = ActivityManager.START_PERMISSION_DENIED;
}
}
...
// 启动当前Activity的Activity
ActivityRecord sourceRecord = null;
// 接收返回结果的Activity
ActivityRecord resultRecord = null;
if (resultTo != null) {
sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
// 需要返回结果,则resultRecord设置为sourceRecord
resultRecord = sourceRecord;
}
}
}
final int launchFlags = intent.getFlags();
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
if (requestCode >= 0) {
// FLAG_ACTIVITY_FORWARD_RESULT和requestCode>=0不能同时设置
// 因为设置了FLAG_ACTIVITY_FORWARD_RESULT后,新启动的Activity会将result透传回操作发起的Activity的源Activity
ActivityOptions.abort(options);
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
// 结果返回到发起者的源Activity
resultRecord = sourceRecord.resultTo;
if (resultRecord != null && !resultRecord.isInStackLocked()) {
resultRecord = null;
}
resultWho = sourceRecord.resultWho;
requestCode = sourceRecord.requestCode;
sourceRecord.resultTo = null;
if (resultRecord != null) {
// 设置FLAG_ACTIVITY_FORWARD_RESULT后,接收结果的Activity就不能再持有接收结果的Activity
resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
}
if (sourceRecord.launchedFromUid == callingUid) {
callingPackage = sourceRecord.launchedFromPackage;
}
}
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// 需要启动的Activity不存在,返回intent无法解析
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
// 找不到类
err = ActivityManager.START_CLASS_NOT_FOUND;
}
...
final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();
if (err != START_SUCCESS) {
// 不能成功启动的情况,则放弃执行
if (resultRecord != null) {
resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
}
ActivityOptions.abort(options);
return err;
}
// 检查是否有启动Activity权限
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity, callerApp,
resultRecord, resultStack, options);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo);
...
if (abort) {
...
return START_ABORTED;
}
...
// 新建需要创建的Activity的对应ActivityRecord
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, options, sourceRecord);
if (outActivity != null) {
outActivity[0] = r;
}
...
// 获取当前接收输入或正在启动Activity的ActivityStack
final ActivityStack