Activity启动流程(基于android-13.0.0_r83)
system_server进程启动Activity
执行ActivityTaskManagerService中的startActivity
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions) {
return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
UserHandle.getCallingUserId());
}
主要步骤
- 快速路径:
如果启动选项包含 transientLaunch 标志,并且调用方是最近任务,则尝试快速启动最近任务。 - 调用方验证:
验证调用方的包名和 UID 是否匹配,并确保调用方不是隔离进程。 - SDK 沙箱:
- 如果调用方是 SDK 沙箱进程,则检查是否允许启动 Activity。
- 目标用户验证:
验证目标用户 ID 是否合法。 - 启动 Activity:
使用 ActivityStarter 启动 Activity,并返回启动结果。
/*
* @param caller 调用方的 IApplicationThread 对象,表示发起启动请求的应用线程。
* @param callingPackage:调用方的包名。
* @param callingFeatureId:调用方的 Feature ID(可以为 null)。
* @param intent:要启动的 Activity 的 Intent。
* @param resolvedType:Intent 的 MIME 类型。
* @param resultTo:接收结果的 IBinder 对象(通常是当前 Activity 的令牌)。
* @param resultWho:接收结果的标识符。
* @param startFlags:启动标志位。
* @param profilerInfo:性能分析信息(可以为 null)
* @param bOptions:启动选项(如动画、过渡效果等)。
* @param userId:目标用户 ID。
* @param validateIncomingUser:是否验证传入的用户 ID。
*
* @return 返回一个整数值,表示启动结果(如 ActivityManager.START_SUCCESS)。
*/
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
@Nullable String callingFeatureId, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int startFlags,
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
//处理启动选项
//将传入的 Bundle 启动选项转换为 SafeActivityOptions 对象。
//SafeActivityOptions 是对 ActivityOptions 的封装,用于确保启动选项的安全性。
final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
// 快速路径:启动最近任务
// 如果启动选项包含 transientLaunch 标志,并且调用方是最近任务(Recents),则尝试快速启动最近任务。
if (opts != null && opts.getOriginalOptions().getTransientLaunch()
&& isCallerRecents(Binder.getCallingUid())) {
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
//尝试启动现有的最近任务。
if (mActivityStartController.startExistingRecentsIfPossible(
intent, opts.getOriginalOptions())) {
//如果成功,则返回 ActivityManager.START_TASK_TO_FRONT,表示任务已前置。
return ActivityManager.START_TASK_TO_FRONT;
}
// Else follow the standard launch procedure.
}
} finally {
//清除和恢复调用方的身份信息,确保在系统权限下执行操作。
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
Binder.restoreCallingIdentity(origId);
}
}
//验证调用方的包名是否与调用方的 UID 匹配。
assertPackageMatchesCallingUid(callingPackage);
//确保调用方不是隔离进程(isolated process)。
enforceNotIsolatedCaller("startActivityAsUser");
//如果调用方是 SDK 沙箱进程,则检查是否允许启动 Activity。
if (Process.isSdkSandboxUid(Binder.getCallingUid())) {
SdkSandboxManagerLocal sdkSandboxManagerLocal = LocalManagerRegistry.getManager(
SdkSandboxManagerLocal.class);
if (sdkSandboxManagerLocal == null) {
throw new IllegalStateException("SdkSandboxManagerLocal not found when starting"
+ " an activity from an SDK sandbox uid.");
}
//验证 Intent 的合法性。
sdkSandboxManagerLocal.enforceAllowedToStartActivity(intent);
}
//验证目标用户 ID 是否合法。
//如果 validateIncomingUser 为 true,则进一步验证传入的用户 ID。
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
// 获取一个 ActivityStarter 实例,用于启动 Activity。
//设置参数,设置调用方、包名、Feature ID、MIME 类型、结果接收者、请求代码、启动标志位、性能分析信息、启动选项和目标用户 ID。
//execute:执行启动操作,并返回启动结果。
return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
.setCaller(caller)
.setCallingPackage(callingPackage)
.setCallingFeatureId(callingFeatureId)
.setResolvedType(resolvedType)
.setResultTo(resultTo)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setStartFlags(startFlags)
.setProfilerInfo(profilerInfo)
.setActivityOptions(opts)
.setUserId(userId)
.execute();
}
执行ActivityStarter 中的execute
ActivityStarter
它是 ActivityTaskManagerService(ATMS)的一部分,负责处理 Activity 启动的复杂逻辑,包括解析 Intent、处理启动模式、管理任务栈等。ActivityStarter 的设计目标是将 Activity 启动的逻辑集中化,便于维护和扩展。
主要作用
- 解析 Intent: 解析启动 Activity 的 Intent,确定目标 Activity。
- 处理启动模式: 根据 Activity 的启动模式(如 standard、singleTop、singleTask 等)决定是否创建新的 Activity 实例或复用现有实例。
- 管理任务栈: 确定目标 Activity 应该运行在哪个任务栈(Task)中。
- 处理权限和安全性: 检查调用方是否有权限启动目标 Activity。
- 处理多窗口模式: 在多窗口模式下,确定 Activity 的显示位置和大小。
- 调用生命周期方法: 触发目标 Activity 的生命周期方法(如 onCreate()、onStart()、onResume())。
execute()
- mRequest:表示Activity启动请求的对象,包含了启动Activity所需的所有信息,如Intent、调用者信息、权限等。
- mService:表示系统的全局服务,可能是 ActivityManagerService 或类似的系统服务。
- mSupervisor:ActivityStackSupervisor,负责管理Activity栈和任务。
- mRootWindowContainer:表示窗口容器的根节点,管理所有显示器的窗口和任务栈。
//frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java
/*
* 方法负责执行一个Activity启动请求,处理从请求开始到结束的整个流程
*/
int execute() {
try {
//可能是用于通知系统或记录日志,表示Activity启动流程已经开始
onExecutionStarted();
//文件描述符检查:检查Intent中是否包含文件描述符。如果包含,抛出 IllegalArgumentException 异常,防止文件描述符泄漏
if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
final LaunchingState launchingState;
synchronized (mService.mGlobalLock) {
//获取调用者的 ActivityRecord,用于标识启动Activity的调用者
final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
//获取调用者的UID,用于权限检查
final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
? Binder.getCallingUid() : mRequest.realCallingUid;
//记录Activity的启动状态。这个步骤可能用于性能监控或日志记录
launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
mRequest.intent, caller, callingUid);
}
//表示调用者尚未解析目标Activity,此时调用 mRequest.resolveActivity(mSupervisor) 进行解析。
if (mRequest.activityInfo == null) {
//确保在启动Activity之前,目标Activity的信息已经被正确解析
mRequest.resolveActivity(mSupervisor);
}
// 如果Intent的Action是 ACTION_REQUEST_SHUTDOWN、ACTION_SHUTDOWN 或 ACTION_REBOOT,表示系统正在执行关机或重启操作。
if (mRequest.intent != null) {
String intentAction = mRequest.intent.getAction();
String callingPackage = mRequest.callingPackage;
if (intentAction != null && callingPackage != null
&& (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_REBOOT.equals(intentAction))) {
//可能是为了在系统重启后能够恢复现场
ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
}
}
int res;
synchronized (mService.mGlobalLock) {
//检查全局配置是否发生变化(globalConfigWillChange)。如果发生变化,更新配置并通知相关组件。
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (rootTask != null) {
rootTask.mConfigWillChange = globalConfigWillChange;
}
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
+ "will change = %b", globalConfigWillChange);
final long origId = Binder.clearCallingIdentity();
//检查是否需要切换到重量级Activity(例如,从普通Activity切换到分屏模式)。如果需要切换,返回相应的结果。
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
//执行实际的Activity启动请求
res = executeRequest(mRequest);
//用于清除和恢复调用者的身份信息,确保在执行关键操作时权限正确。
Binder.restoreCallingIdentity(origId);
if (globalConfigWillChange) {
mService.mAmInternal.enforceCallingPermission(
android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
if (rootTask != null) {
//标记任务栈的配置是否发生变化
rootTask.mConfigWillChange = false;
}
ProtoLog.v(WM_DEBUG_CONFIGURATION,
"Updating to new configuration after starting activity.");
//更新系统的全局配置
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
final ActivityOptions originalOptions = mRequest.activityOptions != null
? mRequest.activityOptions.getOriginalOptions() : null;
final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
// 通知 ActivityMetricsLogger,Activity已经启动。这一步可能用于记录Activity启动的性能数据。
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
newActivityCreated, mLastStartActivityRecord, originalOptions);
if (mRequest.waitResult != null) {
mRequest.waitResult.result = res;
//如果需要等待启动结果,调用此方法进行等待
res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
launchingState);
}
//将内部的结果转换为外部可用的结果并返回
return getExternalResult(res);
}
} finally {
//用于释放资源或执行一些清理操作
onExecutionComplete();
}
}
executeRequest
executeRequest比较长分部分分析,主要分为5个部分
- 准备参数
- 各类权限检测
- 启动过程拦截器处理
- 构建待启动的目标 Activity 对应的 ActivityRecord 对象
- 调用 startActivityUnchecked 方法
- 参数准备
- 检查 request.reason:确保启动请求有一个明确的原因,否则抛出异常。
- 记录启动信息:保存启动原因、启动时间等,用于日志记录或调试。
- 提取请求参数:从 Request 对象中提取启动 Activity 所需的各种参数,如 Intent、ActivityInfo、callingUid、callingPackage 等。
private int executeRequest(Request request) {
//检查确保每个Activity启动请求都有一个明确的原因,可能是为了日志记录、调试或权限控制
if (TextUtils.isEmpty(request.reason)) {
throw new IllegalArgumentException("Need to specify a reason.");
}
mLastStartReason = request.reason;
mLastStartActivityTimeMs = System.currentTimeMillis();//记录当前时间
mLastStartActivityRecord = null;
//提取请求参数
final IApplicationThread caller = request.caller;
Intent intent = request.intent;
NeededUriGrants intentGrants = request.intentGrants;//表示Intent所需的URI权限
String resolvedType = request.resolvedType;
ActivityInfo aInfo = request.activityInfo;//表示目标Activity的信息(如包名、类名、权限等)
ResolveInfo rInfo = request.resolveInfo;//表示解析Intent后得到的目标组件信息
final IVoiceInteractionSession voiceSession = request.voiceSession;
final IBinder resultTo = request.resultTo;
String resultWho = request.resultWho;
int requestCode = request.requestCode;
int callingPid = request.callingPid;
int callingUid = request.callingUid;
String callingPackage = request.callingPackage;
String callingFeatureId = request.callingFeatureId;
final int realCallingPid = request.realCallingPid;
final int realCallingUid = request.realCallingUid;
final int startFlags = request.startFlags;
final SafeActivityOptions options = request.activityOptions;
Task inTask = request.inTask;//表示目标Activity所属的任务栈
TaskFragment inTaskFragment = request.inTaskFragment;
...
}
- 权限检查
检查WindowProcessController能不能获取,如果不能,报权限异常。
private int executeRequest(Request request) {
int err = ActivityManager.START_SUCCESS;
// 这是一个可选的数据包,用于应用安装验证
final Bundle verificationBundle =
options != null ? options.popAppVerificationBundle() : null;
//存储调用者进程的信息
WindowProcessController callerApp = null;
//caller 是一个 IApplicationThread 对象,表示调用者进程的 Binder 接口
if (caller != null) {
//获取调用者进程的 WindowProcessController 对象,
//WindowProcessController 是 Android 系统中用于管理进程状态的对象,包含进程的 PID、UID 等信息
callerApp = mService.getProcessController(caller);
if (callerApp != null) {
//提取调用者的 PID 和 UID
callingPid = callerApp.getPid();
callingUid = callerApp.mInfo.uid;
} else {
//记录警告日志并设置错误码
Slog.w(TAG, "Unable to find app for caller " + caller + " (pid=" + callingPid
+ ") when starting: " + intent.toString());
err = START_PERMISSION_DENIED;
}
}
//初始化 userId
final int userId = aInfo != null && aInfo.applicationInfo != null
? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
if (err == ActivityManager.START_SUCCESS) {
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
+ "} from uid " + callingUid);
}
...
}
startActivityForResult相关业务处理,主要确定是不是这个业务,如果是,找到正确的sourceRecord和resultRecord。
private int executeRequest(Request request) {
//存储发起请求的Activity记录
ActivityRecord sourceRecord = null;
//存储结果返回的目标Activity记录
ActivityRecord resultRecord = null;
//是一个 IBinder 对象,表示请求结果的接收者
if (resultTo != null) {
sourceRecord = ActivityRecord.isInAnyTask(resultTo);
if (DEBUG_RESULTS) {
Slog.v(TAG_RESULTS, "Will send result to " + resultTo + " " + sourceRecord);
}
if (sourceRecord != null) {
if (requestCode >= 0 && !sourceRecord.finishing) {
resultRecord = sourceRecord;
}
}
}
final int launchFlags = intent.getFlags();
if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
// Transfer the result target from the source activity to the new one being started,
// including any failures.
if (requestCode >= 0) {
SafeActivityOptions.abort(options);
return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
}
resultRecord = sourceRecord.resultTo;
if (resultRecord != null && !resultRecord.isInRootTaskLocked()) {
resultRecord = null;
}
resultWho = sourceRecord.resultWho;
requestCode = sourceRecord.requestCode;
sourceRecord.resultTo = null;
if (resultRecord != null) {
resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
}
if (sourceRecord.launchedFromUid == callingUid) {
callingPackage = sourceRecord.launchedFromPackage;
callingFeatureId = sourceRecord.launchedFromFeatureId;
}
}
if (err == ActivityManager.START_SUCCESS && intent.getComponent() == null) {
// We couldn't find a class that can handle the given Intent.
// That's the end of that!
err = ActivityManager.START_INTENT_NOT_RESOLVED;
}
if (err == ActivityManager.START_SUCCESS && aInfo == null) {
// We couldn't find the specific class specified in the Intent.
// Also the end of the line.
err = ActivityManager.START_CLASS_NOT_FOUND;
}
if (err == ActivityManager.START_SUCCESS && sourceRecord != null
&& sourceRecord.getTask().voiceSession != null) {
if ((launchFlags & FLAG_ACTIVITY_NEW_TASK) == 0
&& sourceRecord.info.applicationInfo.uid != aInfo.applicationInfo.uid) {
try {
intent.addCategory(Intent.CATEGORY_VOICE);
if (!mService.getPackageManager().activitySupportsIntent(
intent.getComponent(), intent, resolvedType)) {
Slog.w(TAG, "Activity being started in current voice task does not support "
+ "voice: " + intent);
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
}
} catch (RemoteException e) {
Slog.w(TAG, "Failure checking voice capabilities", e);
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
}
}
}
if (err == ActivityManager.START_SUCCESS && voiceSession != null) {
// If the caller is starting a new voice session, just make sure the target
// is actually allowing it to run this way.
try {
if (!mService.getPackageManager().activitySupportsIntent(intent.getComponent(),
intent, resolvedType)) {
Slog.w(TAG,
"Activity being started in new voice task does not support: " + intent);
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
}
} catch (RemoteException e) {
Slog.w(TAG, "Failure checking voice capabilities", e);
err = ActivityManager.START_NOT_VOICE_COMPATIBLE;
}
}
final Task resultRootTask = resultRecord == null
? null : resultRecord.getRootTask();
if (err != START_SUCCESS) {
if (resultRecord != null) {
resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
null /* data */, null /* dataGrants */);
}
SafeActivityOptions.abort(options);
return err;
}
通过ATS、ActivityManager、PermissionPolicyService检查是否有启动Activity的权限,如果没有终止启动。
private int executeRequest(Request request) {
//权限检查返回的 abort 为 false,表示有权限启动目标 Activity
boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
requestCode, callingPid, callingUid, callingPackage, callingFeatureId,
request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord,
resultRootTask);
abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
callingPid, resolvedType, aInfo.applicationInfo);
abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,
callingPackage);
// Merge the two options bundles, while realCallerOptions takes precedence.
ActivityOptions checkedOptions = options != null
? options.getOptions(intent, aInfo, callerApp, mSupervisor) : null;
//后台启动控制
@BalCode int balCode = BAL_ALLOW_DEFAULT;
if (!abort) {
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER,
"shouldAbortBackgroundActivityStart");
BackgroundActivityStartController balController =
mController.getBackgroundActivityLaunchController();
balCode =
balController.checkBackgroundActivityStart(
callingUid,
callingPid,
callingPackage,
realCallingUid,
realCallingPid,
callerApp,
request.originatingPendingIntent,
request.allowBackgroundActivityStart,
intent,
checkedOptions);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
}
if (request.allowPendingRemoteAnimationRegistryLookup) {
checkedOptions = mService.getActivityStartController()
.getPendingRemoteAnimationRegistry()
.overrideOptionsIfNeeded(callingPackage, checkedOptions);
}
if (mService.mController != null) {
try {
// The Intent we give to the watcher has the extra data stripped off, since it
// can contain private information.
Intent watchIntent = intent.cloneFilter();
abort |= !mService.mController.activityStarting(watchIntent,
aInfo.applicationInfo.packageName);
} catch (RemoteException e) {
mService.mController = null;
}
}
启动过程拦截器处理,调用ActivityStartInterceptor的intercept方法对满足条件进行activity启动拦截。
private int executeRequest(Request request) {
mInterceptor.setStates(userId, realCallingPid, realCallingUid, startFlags, callingPackage,
callingFeatureId);
if (mInterceptor.intercept(intent, rInfo, aInfo, resolvedType, inTask, inTaskFragment,
callingPid, callingUid, checkedOptions)) {
// activity start was intercepted, e.g. because the target user is currently in quiet
// mode (turn off work) or the target application is suspended
intent = mInterceptor.mIntent;
rInfo = mInterceptor.mRInfo;
aInfo = mInterceptor.mAInfo;
resolvedType = mInterceptor.mResolvedType;
inTask = mInterceptor.mInTask;
callingPid = mInterceptor.mCallingPid;
callingUid = mInterceptor.mCallingUid;
checkedOptions = mInterceptor.mActivityOptions;
// The interception target shouldn't get any permission grants
// intended for the original destination
intentGrants = null;
}
if (abort) {
if (resultRecord != null) {
resultRecord.sendResult(INVALID_UID, resultWho, requestCode, RESULT_CANCELED,
null /* data */, null /* dataGrants */);
}
// We pretend to the caller that it was really started, but they will just get a
// cancel result.
ActivityOptions.abort(checkedOptions);
return START_ABORTED;
}
if (aInfo != null) {
if (mService.getPackageManagerInternalLocked().isPermissionsReviewRequired(
aInfo.packageName, userId)) {
final IIntentSender target = mService.getIntentSenderLocked(
ActivityManager.INTENT_SENDER_ACTIVITY, callingPackage, callingFeatureId,
callingUid, userId, null, null, 0, new Intent[]{intent},
new String[]{resolvedType}, PendingIntent.FLAG_CANCEL_CURRENT
| PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
int flags = intent.getFlags();
flags |= Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
if ((flags & (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NEW_DOCUMENT)) != 0) {
flags |= Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
}
newIntent.setFlags(flags);
newIntent.putExtra(Intent.EXTRA_PACKAGE_NAME, aInfo.packageName);
newIntent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
if (resultRecord != null) {
newIntent.putExtra(Intent.EXTRA_RESULT_NEEDED, true);
}
intent = newIntent;
intentGrants = null;
resolvedType = null;
callingUid = realCallingUid;
callingPid = realCallingPid;
rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId, 0,
computeResolveFilterUid(
callingUid, realCallingUid, request.filterCallingUid));
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags,
null /*profilerInfo*/);
if (DEBUG_PERMISSIONS_REVIEW) {
final Task focusedRootTask =
mRootWindowContainer.getTopDisplayFocusedRootTask();
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true,
true, false) + "} from uid " + callingUid + " on display "
+ (focusedRootTask == null ? DEFAULT_DISPLAY
: focusedRootTask.getDisplayId()));
}
}
}
if (rInfo != null && rInfo.auxiliaryInfo != null) {
intent = createLaunchIntent(rInfo.auxiliaryInfo, request.ephemeralIntent,
callingPackage, callingFeatureId, verificationBundle, resolvedType, userId);
resolvedType = null;
callingUid = realCallingUid;
callingPid = realCallingPid;
// The ephemeral installer shouldn't get any permission grants
// intended for the original destination
intentGrants = null;
aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, null /*profilerInfo*/);
}
// TODO (b/187680964) Correcting the caller/pid/uid when start activity from shortcut
// Pending intent launched from systemui also depends on caller app
if (callerApp == null && realCallingPid > 0) {
final WindowProcessController wpc = mService.mProcessMap.getProcess(realCallingPid);
if (wpc != null) {
callerApp = wpc;
}
}
创建启动目标Activity的ActivityRecord。
调用 startActivityUnchecked 方法
private int executeRequest(Request request) {
final ActivityRecord r = new ActivityRecord.Builder(mService)
.setCaller(callerApp)
.setLaunchedFromPid(callingPid)
.setLaunchedFromUid(callingUid)
.setLaunchedFromPackage(callingPackage)
.setLaunchedFromFeature(callingFeatureId)
.setIntent(intent)
.setResolvedType(resolvedType)
.setActivityInfo(aInfo)
.setConfiguration(mService.getGlobalConfiguration())
.setResultTo(resultRecord)
.setResultWho(resultWho)
.setRequestCode(requestCode)
.setComponentSpecified(request.componentSpecified)
.setRootVoiceInteraction(voiceSession != null)
.setActivityOptions(checkedOptions)
.setSourceRecord(sourceRecord)
.build();
mLastStartActivityRecord = r;
if (r.appTimeTracker == null && sourceRecord != null) {
// If the caller didn't specify an explicit time tracker, we want to continue
// tracking under any it has.
r.appTimeTracker = sourceRecord.appTimeTracker;
}
WindowProcessController homeProcess = mService.mHomeProcess;
boolean isHomeProcess = homeProcess != null
&& aInfo.applicationInfo.uid == homeProcess.mUid;
if (balCode != BAL_BLOCK && !isHomeProcess) {
mService.resumeAppSwitches();
}
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, true /* doResume */, checkedOptions,
inTask, inTaskFragment, balCode, intentGrants);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
}
return mLastStartActivityResult;
}
startActivityUnchecked
负责在完成初步校验后执行具体的启动流程。
/*
* @param r 目标Activity的记录。
* @param sourceRecord:发起启动请求的Activity记录。
* @param voiceSession:语音交互相关参数。
* @param voiceInteractor:。
* @param startFlags:启动标志(如FLAG_ACTIVITY_NEW_TASK)。
* @param doResume:是否立即恢复目标Activity。
* @param options:启动选项(如动画、窗口模式)。
* @param inTask:目标Activity所属的Task和TaskFragment。
* @param inTaskFragment:
* @param balCode:后台启动检查的结果代码。
* @param intentGrants:URI权限授予信息。
*
* @return 启动结果(如START_SUCCESS、START_CANCELED)。
*/
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, @BalCode int balCode,
NeededUriGrants intentGrants) {
int result = START_CANCELED;//默认启动失败
final Task startedActivityRootTask;
// Transition管理
// 创建Transition对象以记录启动过程中的动画和状态变化
// 仅在未收集Transition且存在TransitionPlayer时创建新Transition
final TransitionController transitionController = r.mTransitionController;
Transition newTransition = (!transitionController.isCollecting()
&& transitionController.getTransitionPlayer() != null)
? transitionController.createTransition(TRANSIT_OPEN) : null;
RemoteTransition remoteTransition = r.takeRemoteTransition();
try {
//延迟窗口布局更新,避免启动过程中的布局抖动
mService.deferWindowLayout();
//收集目标Activity的状态
transitionController.collect(r);
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
//启动核心逻辑
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
startFlags, doResume, options, inTask, inTaskFragment, balCode,
intentGrants);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
//处理启动结果,返回目标Activity的根Task
startedActivityRootTask = handleStartResult(r, options, result, newTransition,
remoteTransition);
}
} finally {
//确保无论启动成功与否,窗口布局最终恢复
mService.continueWindowLayout();
}
//在启动完成后执行后续处理逻辑(如日志记录、回调通知)
postStartActivityProcessing(r, result, startedActivityRootTask);
return result;
}
startActivityInner
启动一个activity,包括任务(Task)的管理、Activity 的复用、权限检查、任务栈的调整等。
@VisibleForTesting
int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment, @BalCode int balCode,
NeededUriGrants intentGrants) {
//初始化了启动 Activity 所需的状态
setInitialState(r, options, inTask, inTaskFragment, doResume, startFlags, sourceRecord,
voiceSession, voiceInteractor, balCode);
//计算启动 Activity 时所需的标志位(flags),这些标志位决定了 Activity 如何启动(例如是否在新的任务栈中启动)
computeLaunchingTaskFlags();
mIntent.setFlags(mLaunchFlags);
boolean dreamStopping = false;
//检查是否有正在停止的 Dream Activity(例如屏保或屏保类应用)
for (ActivityRecord stoppingActivity : mSupervisor.mStoppingActivities) {
if (stoppingActivity.getActivityType()
== WindowConfiguration.ACTIVITY_TYPE_DREAM) {
dreamStopping = true;
break;
}
}
// 获取当前显示区域(DisplayArea)中聚焦的根任务栈(RootTask)以及顶部的任务栈(Task).
final Task prevTopRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
final Task prevTopTask = prevTopRootTask != null ? prevTopRootTask.getTopLeafTask() : null;
final Task reusedTask = getReusableTask();//尝试获取一个可以复用的任务栈,避免创建新的任务栈
// 如果启动 Activity 时需要冻结最近任务列表(例如从最近任务列表中启动应用),则设置冻结标志,防止任务列表重新排序
if (mOptions != null && mOptions.freezeRecentTasksReordering()
&& mSupervisor.mRecentTasks.isCallerRecents(r.launchedFromUid)
&& !mSupervisor.mRecentTasks.isFreezeTaskListReorderingSet()) {
mFrozeTaskList = true;
mSupervisor.mRecentTasks.setFreezeTaskListReordering();
}
//计算目标任务栈
//如果存在可复用的任务栈,则使用该任务栈;否则,调用 computeTargetTask() 计算一个新的目标任务栈
final Task targetTask = reusedTask != null ? reusedTask : computeTargetTask();
final boolean newTask = targetTask == null;//表示是否需要在新的任务栈中启动 Activity
mTargetTask = targetTask;
computeLaunchParams(r, sourceRecord, targetTask);
// 检查当前是否有权限启动目标 Activity。如果没有权限,则返回错误码,并通知调用方启动失败
int startResult = isAllowedToStart(r, newTask, targetTask);
if (startResult != START_SUCCESS) {
if (r.resultTo != null) {
r.resultTo.sendResult(INVALID_UID, r.resultWho, r.requestCode, RESULT_CANCELED,
null /* data */, null /* dataGrants */);
}
return startResult;
}
//如果目标任务栈不为空,并且栈顶有未结束的 Activity,则尝试复用该任务栈
//如果复用失败,则设置 mAddingToTask 标志,表示需要将 Activity 添加到现有任务栈中。
if (targetTask != null) {
mPriorAboveTask = TaskDisplayArea.getRootTaskAbove(targetTask.getRootTask());
}
final ActivityRecord targetTaskTop = newTask
? null : targetTask.getTopNonFinishingActivity();
if (targetTaskTop != null) {
// Recycle the target task for this launch.
startResult = recycleTask(targetTask, targetTaskTop, reusedTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
} else {
mAddingToTask = true;
}
// 如果当前有聚焦的根任务栈,则检查是否需要将启动的 Activity 交付给当前顶部的 Activity 处理
final Task topRootTask = mPreferredTaskDisplayArea.getFocusedRootTask();
if (topRootTask != null) {
startResult = deliverToCurrentTopIfNeeded(topRootTask, intentGrants);
if (startResult != START_SUCCESS) {
return startResult;
}
}
//创建或获取根任务栈
if (mTargetRootTask == null) {
mTargetRootTask = getOrCreateRootTask(mStartActivity, mLaunchFlags, targetTask,
mOptions);
}
if (newTask) {
final Task taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null)
? mSourceRecord.getTask() : null;
//如果需要在新任务栈中启动 Activity,则调用 setNewTask() 设置新任务栈
setNewTask(taskToAffiliate);
} else if (mAddingToTask) {
//将 Activity 添加到现有任务栈中
addOrReparentStartingActivity(targetTask, "adding to task");
}
//如果不需要避免将任务栈移到前台,并且需要恢复 Activity,则将目标根任务栈移到前台
//如果当前系统处于 Dream 模式(例如屏保),并且目标根任务栈不在顶部,则设置 mLaunchTaskBehind 标志,表示 Activity 需要在后台启动
if (!mAvoidMoveToFront && mDoResume) {
mTargetRootTask.getRootTask().moveToFront("reuseOrNewTask", targetTask);
if (!mTargetRootTask.isTopRootTaskInDisplayArea() && mService.isDreaming()
&& !dreamStopping) {
mLaunchTaskBehind = true;
r.mLaunchTaskBehind = true;
}
}
//授予目标 Activity 所需的 URI 权限
mService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants,
mStartActivity.getUriPermissionsLocked());
//如果启动的 Activity 需要返回结果给调用方,则授予调用方隐式访问权限
if (mStartActivity.resultTo != null && mStartActivity.resultTo.info != null) {
final PackageManagerInternal pmInternal =
mService.getPackageManagerInternalLocked();
final int resultToUid = pmInternal.getPackageUid(
mStartActivity.resultTo.info.packageName, 0 /* flags */,
mStartActivity.mUserId);
pmInternal.grantImplicitAccess(mStartActivity.mUserId, mIntent,
UserHandle.getAppId(mStartActivity.info.applicationInfo.uid) /*recipient*/,
resultToUid /*visible*/, true /*direct*/);
}
//记录任务和 Activity 的创建
final Task startedTask = mStartActivity.getTask();
if (newTask) {
EventLogTags.writeWmCreateTask(mStartActivity.mUserId, startedTask.mTaskId);
}
mStartActivity.logStartActivity(EventLogTags.WM_CREATE_ACTIVITY, startedTask);
mStartActivity.getTaskFragment().clearLastPausedActivity();
mRootWindowContainer.startPowerModeLaunchIfNeeded(
false /* forceSend */, mStartActivity);
final boolean isTaskSwitch = startedTask != prevTopTask && !startedTask.isEmbedded();
mTargetRootTask.startActivityLocked(mStartActivity, topRootTask, newTask, isTaskSwitch,
mOptions, sourceRecord);
//如果需要恢复 Activity,则确保目标根任务栈中的 Activity 可见。
//如果目标根任务栈的顶部 Activity 不可聚焦(例如画中画模式),则确保所有 Activity 可见,并执行应用过渡动画。
//否则,将目标根任务栈移到前台,并恢复其顶部 Activity。
if (mDoResume) {
final ActivityRecord topTaskActivity = startedTask.topRunningActivityLocked();
if (!mTargetRootTask.isTopActivityFocusable()
|| (topTaskActivity != null && topTaskActivity.isTaskOverlay()
&& mStartActivity != topTaskActivity)) {
mTargetRootTask.ensureActivitiesVisible(null /* starting */,
0 /* configChanges */, !PRESERVE_WINDOWS);
mTargetRootTask.mDisplayContent.executeAppTransition();
} else {
if (mTargetRootTask.isTopActivityFocusable()
&& !mRootWindowContainer.isTopDisplayFocusedRootTask(mTargetRootTask)) {
mTargetRootTask.moveToFront("startActivityInner");
}
mRootWindowContainer.resumeFocusedTasksTopActivities(
mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
}
}
//更新用户的任务栈信息
mRootWindowContainer.updateUserRootTask(mStartActivity.mUserId, mTargetRootTask);
// 将启动的任务栈添加到最近任务列表中
mSupervisor.mRecentTasks.add(startedTask);
//处理不可调整大小的任务栈(例如固定方向的任务栈)
mSupervisor.handleNonResizableTaskIfNeeded(startedTask,
mPreferredWindowingMode, mPreferredTaskDisplayArea, mTargetRootTask);
// 如果启动的 Activity 需要进入画中画模式(PIP),则将其移动到画中画任务栈中.
if (mOptions != null && mOptions.isLaunchIntoPip()
&& sourceRecord != null && sourceRecord.getTask() == mStartActivity.getTask()
&& balCode != BAL_BLOCK) {
mRootWindowContainer.moveActivityToPinnedRootTask(mStartActivity,
sourceRecord, "launch-into-pip");
}
return START_SUCCESS;
}
resumeFocusedTasksTopActivities
resumeTopActivityUncheckedLocked
resumeTopActivityInnerLocked
schedulePauseActivity
在启动Activity之前,将App进程中的Activity暂停
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
void schedulePauseActivity(ActivityRecord prev, boolean userLeaving,
boolean pauseImmediately, boolean autoEnteringPip, String reason) {
ProtoLog.v(WM_DEBUG_STATES, "Enqueueing pending pause: %s", prev);
try {
EventLogTags.writeWmPauseActivity(prev.mUserId, System.identityHashCode(prev),
prev.shortComponentName, "userLeaving=" + userLeaving, reason);
mAtmService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
prev.token, PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately, autoEnteringPip));
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
mPausingActivity = null;
mLastPausedActivity = null;
mTaskSupervisor.mNoHistoryActivities.remove(prev);
}
}
resumeTopActivity
//frameworks/base/services/core/java/com/android/server/wm/TaskFragment.java
final boolean resumeTopActivity(ActivityRecord prev, ActivityOptions options,
boolean deferPause) {
...
//
mTaskSupervisor.startSpecificActivity(next, true, true);
...
}
startSpecificActivity
检查目标 Activity 所在的应用程序进程是否已经运行,并根据进程状态决定是直接启动 Activity 还是先启动应用程序进程
//frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
// Is this activity's application already running?
final WindowProcessController wpc =
mService.getProcessController(r.processName, r.info.applicationInfo.uid);
boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
try {
//如果目标进程已经运行且存活(wpc.hasThread() 为 true),则调用 realStartActivityLocked 方法直接启动 Activity。
//realStartActivityLocked 是真正启动 Activity 的核心方法,负责将 Activity 添加到任务栈中并触发其生命周期回调。
realStartActivityLocked(r, wpc, andResume, checkConfig);
return;
} catch (RemoteException e) {
Slog.w(TAG, "Exception when starting activity "
+ r.intent.getComponent().flattenToShortString(), e);
}
// If a dead object exception was thrown -- fall through to
// restart the application.
knownToBeDead = true;
// Remove the process record so it won't be considered as alive.
mService.mProcessNames.remove(wpc.mName, wpc.mUid);
mService.mProcessMap.remove(wpc.getPid());
}
//如果进程已经死亡,则调用 notifyUnknownVisibilityLaunchedForKeyguardTransition 方法通知系统,目标 Activity 的可见性状态可能发生变化(例如从锁屏界面启动 Activity)
r.notifyUnknownVisibilityLaunchedForKeyguardTransition();
//如果目标进程不存在或已经死亡,则调用 mService.startProcessAsync 方法异步启动应用程序进程。
final boolean isTop = andResume && r.isTopRunningActivity();
//isTop 表示目标 Activity 是否是当前顶部的 Activity
//knownToBeDead 表示目标进程是否已经死亡
mService.startProcessAsync(r, knownToBeDead, isTop,
isTop ? HostingRecord.HOSTING_TYPE_TOP_ACTIVITY
: HostingRecord.HOSTING_TYPE_ACTIVITY);
}
标签:启动,学习,intent,&&,Activity,相关,null,final
From: https://blog.csdn.net/linwq8/article/details/145536752