Activity启动源码分析-基于Android10(三)


文章目录

  • Activity启动-IPC后续
    • 1.ActivityStarter
    • 二.RootActivityContainer
    • 三.ActivityStack

Activity启动源码分析-基于Android10(三)
文章图片

  • Instrumentation
    负责调用Activity和Application生命周期。
  • ActivityTaskManagerService
    负责Activity管理和调度等工作。android10中新增的
  • ActivityManagerService
    负责管理四大组件和进程,包括生命周期和状态切换。
  • ActivityTaskManagerInternal
    ActivityTaskManagerService对外提供的一个抽象类,真正的实现在ActivityTaskManagerService#LocalService
  • ActivityThread
    管理应用程序进程中主线程的执行
  • ActivityStackSupervisor
    负责所有Activity栈的管理
  • TransactionExecutor
    主要作用是执行ClientTransaction
  • ClientLifecycleManager
    生命周期的管理调用
Activity启动-IPC后续 1.ActivityStarter 上一篇文章阐述了Activity到ActivityTaskManagerService的通讯机制Activity启动流程-基于Android10(二)今天将更加深入的学习启动流程。
ActivityTaskManagerService#startActivityAsUser:
frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.javaint startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivityAsUser"); userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. return getActivityStartController().obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) .execute(); } // ...省略部分代码 ActivityStartController getActivityStartController() { return mActivityStartController; }

frameworks\base\services\core\java\com\android\server\wm\ActivityStartController.java /** * @return A starter to configure and execute starting an activity. It is valid until after *{@link ActivityStarter#execute} is invoked. At that point, the starter should be *considered invalid and no longer modified or used. */ ActivityStarter obtainStarter(Intent intent, String reason) { return mFactory.obtain().setIntent(intent).setReason(reason); }

Activity通过IActivityTaskManager.aidl调用了startActivityAsUser方法。最后调用了ActivityStarter的execute方法。
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.java /** * Starts an activity based on the request parameters provided earlier. * @return The starter result. */ int execute() { try { // TODO(b/64750076): Look into passing request directly to these methods to allow // for transactional diffs and preprocessing. if (mRequest.mayWait) { return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid, mRequest.intent, mRequest.resolvedType, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup, mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart); } else { return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent, mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.callingPid, mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.componentSpecified, mRequest.outActivity, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup, mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart); } } finally { onExecutionComplete(); } }

mayWait的赋值是在startActivityAsUser中的setMayWait中,这里传入的true。会走startActivityMayWait逻辑。实际上如果mayWait为false走startActivity逻辑,它们最后都会调用startActivityUnchecked方法。
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.javaprivate int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) { //...省略部分代码 result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity); // ...省略部分代码postStartActivityProcessing(r, result, mTargetStack); return result; }// Note: This method should only be called from {@link startActivity}. private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) {//1. 初始化环境和lunchModeFlags setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession, voiceInteractor, restrictedBgActivity); final int preferredWindowingMode = mLaunchParams.mWindowingMode; computeLaunchingTaskFlags(); computeSourceStack(); mIntent.setFlags(mLaunchFlags); //2. 复用activity逻辑 ActivityRecord reusedActivity = getReusableIntentActivity(); //...省略部分代码// 各种flags的判断 if (reusedActivity != null) {// ...省略部分代码final ActivityStack topStack = mRootActivityContainer.getTopDisplayFocusedStack(); final ActivityRecord topFocused = topStack.getTopActivity(); final ActivityRecord top = topStack.topRunningNonDelayedActivityLocked(mNotTop); final boolean dontStart = top != null && mStartActivity.resultTo == null && top.mActivityComponent.equals(mStartActivity.mActivityComponent) && top.mUserId == mStartActivity.mUserId && top.attachedToProcess() && ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0 || isLaunchModeOneOf(LAUNCH_SINGLE_TOP, LAUNCH_SINGLE_TASK)) // This allows home activity to automatically launch on secondary display when // display added, if home was the top activity on default display, instead of // sending new intent to the home activity on default display. && (!top.isActivityTypeHome() || top.getDisplayId() == mPreferredDisplayId); //singleTop 或者singleInstance的处理 if (dontStart) { // For paranoia, make sure we have correctly resumed the top activity. topStack.mLastPausedActivity = null; if (mDoResume) { mRootActivityContainer.resumeFocusedStacksTopActivities(); } ActivityOptions.abort(mOptions); if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) { // We don't need to start a new activity, and the client said not to do // anything if that is the case, so this is it! return START_RETURN_INTENT_TO_CALLER; }deliverNewIntent(top); // Don't use mStartActivity.task to show the toast. We're not starting a new activity // but reusing 'top'. Fields in mStartActivity may not be fully initialized. mSupervisor.handleNonResizableTaskIfNeeded(top.getTaskRecord(), preferredWindowingMode, mPreferredDisplayId, topStack); return START_DELIVERED_TO_TOP; }boolean newTask = false; final TaskRecord taskToAffiliate = (mLaunchTaskBehind && mSourceRecord != null) ? mSourceRecord.getTaskRecord() : null; // 设置对应task并带到前台 int result = START_SUCCESS; if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) { newTask = true; result = setTaskFromReuseOrCreateNewTask(taskToAffiliate); } else if (mSourceRecord != null) { result = setTaskFromSourceRecord(); } else if (mInTask != null) { result = setTaskFromInTask(); } else { // This not being started from an existing activity, and not part of a new task... // just put it in the top task, though these days this case should never happen. result = setTaskToCurrentTopOrCreateNewTask(); }// ...省略部分代码// 启动Activity mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition, mOptions); // 使Activity可见 if (mDoResume) { // 获取栈顶Activity final ActivityRecord topTaskActivity = mStartActivity.getTaskRecord().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { // If the activity is not focusable, we can't resume it, but still would like to // make sure it becomes visible as it starts (this will also trigger entry // animation). An example of this are PIP activities. // Also, we don't want to resume activities in a task that currently has an overlay // as the starting activity just needs to be in the visible paused state until the // over is removed. mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mTargetStack.getDisplay().mDisplayContent.executeAppTransition(); } else { // If the target stack was not previously focusable (previous top running activity // on that stack was not visible) then any prior calls to move the stack to the // will not update the focused stack.If starting the new activity now allows the // task stack to be focusable, then ensure that we now update the focused stack // accordingly. if (mTargetStack.isFocusable() && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); }// 重要代码 mRootActivityContainer.resumeFocusedStacksTopActivities( mTargetStack, mStartActivity, mOptions); } } else if (mStartActivity != null) { mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord()); } mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(), preferredWindowingMode, mPreferredDisplayId, mTargetStack); return START_SUCCESS; }

ActivityStarter的startActivityUnchecked里面有许多关于flags的判断。这里面用到了一个小技术。关于按位或与的判断,关于这个知识点可以参考Android中巧妙的位运算文章。
二.RootActivityContainer startActivityUnchecked方法最后一段代码:
frameworks\base\services\core\java\com\android\server\wm\ActivityStarter.javaprivate int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) {//...省略部分代码 if (mDoResume) { final ActivityRecord topTaskActivity = mStartActivity.getTaskRecord().topRunningActivityLocked(); if (!mTargetStack.isFocusable() || (topTaskActivity != null && topTaskActivity.mTaskOverlay && mStartActivity != topTaskActivity)) { // If the activity is not focusable, we can't resume it, but still would like to // make sure it becomes visible as it starts (this will also trigger entry // animation). An example of this are PIP activities. // Also, we don't want to resume activities in a task that currently has an overlay // as the starting activity just needs to be in the visible paused state until the // over is removed. mTargetStack.ensureActivitiesVisibleLocked(mStartActivity, 0, !PRESERVE_WINDOWS); // Go ahead and tell window manager to execute app transition for this activity // since the app transition will not be triggered through the resume channel. mTargetStack.getDisplay().mDisplayContent.executeAppTransition(); } else { // If the target stack was not previously focusable (previous top running activity // on that stack was not visible) then any prior calls to move the stack to the // will not update the focused stack.If starting the new activity now allows the // task stack to be focusable, then ensure that we now update the focused stack // accordingly. if (mTargetStack.isFocusable() && !mRootActivityContainer.isTopDisplayFocusedStack(mTargetStack)) { mTargetStack.moveToFront("startActivityUnchecked"); }// 重要代码 mRootActivityContainer.resumeFocusedStacksTopActivities( mTargetStack, mStartActivity, mOptions); } } else if (mStartActivity != null) { mSupervisor.mRecentTasks.add(mStartActivity.getTaskRecord()); } mRootActivityContainer.updateUserStack(mStartActivity.mUserId, mTargetStack); mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTaskRecord(), preferredWindowingMode, mPreferredDisplayId, mTargetStack); return START_SUCCESS; }

如果栈顶的Activity获取焦点,调用RootActivityContainer的resumeFocusedStacksTopActivities方法
frameworks\base\services\core\java\com\android\server\wm\RootActivityContainer.javaboolean resumeFocusedStacksTopActivities( ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {if (!mStackSupervisor.readyToResume()) { return false; }boolean result = false; if (targetStack != null && (targetStack.isTopStackOnDisplay() || getTopDisplayFocusedStack() == targetStack)) { result = targetStack.resumeTopActivityUncheckedLocked(target, targetOptions); }for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) { boolean resumedOnDisplay = false; final ActivityDisplay display = mActivityDisplays.get(displayNdx); for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = display.getChildAt(stackNdx); final ActivityRecord topRunningActivity = stack.topRunningActivityLocked(); if (!stack.isFocusableAndVisible() || topRunningActivity == null) { continue; } if (stack == targetStack) { // Simply update the result for targetStack because the targetStack had // already resumed in above. We don't want to resume it again, especially in // some cases, it would cause a second launch failure if app process was dead. resumedOnDisplay |= result; continue; } if (display.isTopStack(stack) && topRunningActivity.isState(RESUMED)) { // Kick off any lingering app transitions form the MoveTaskToFront operation, // but only consider the top task and stack on that display. stack.executeAppTransition(targetOptions); } else { resumedOnDisplay |= topRunningActivity.makeActiveIfNeeded(target); } } if (!resumedOnDisplay) { // In cases when there are no valid activities (e.g. device just booted or launcher // crashed) it's possible that nothing was resumed on a display. Requesting resume // of top activity in focused stack explicitly will make sure that at least home // activity is started and resumed, and no recursion occurs. final ActivityStack focusedStack = display.getFocusedStack(); if (focusedStack != null) { focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions); } } }return result; }

最后调用了ActivityStack的resumeTopActivityUncheckedLocked方法。
三.ActivityStack ActivityStack的resumeTopActivityUncheckedLocked代码:
frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java @GuardedBy("mService") boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) { if (mInResumeTopActivity) { // Don't even start recursing. return false; }boolean result = false; try { // Protect against recursion. mInResumeTopActivity = true; result = resumeTopActivityInnerLocked(prev, options); // When resuming the top activity, it may be necessary to pause the top activity (for // example, returning to the lock screen. We suppress the normal pause logic in // {@link #resumeTopActivityUncheckedLocked}, since the top activity is resumed at the // end. We call the {@link ActivityStackSupervisor#checkReadyForSleepLocked} again here // to ensure any necessary pause logic occurs. In the case where the Activity will be // shown regardless of the lock screen, the call to // {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped. final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */); if (next == null || !next.canTurnScreenOn()) { checkReadyForSleep(); } } finally { mInResumeTopActivity = false; }return result; }// ...省略部分代码 @GuardedBy("mService") private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {// ...省略部分代码 } catch (Exception e) { // Whoops, need to restart this activity! if (DEBUG_STATES) Slog.v(TAG_STATES, "Resume failed; resetting state to " + lastState + ": " + next); next.setState(lastState, "resumeTopActivityInnerLocked"); // lastResumedActivity being non-null implies there is a lastStack present. if (lastResumedActivity != null) { lastResumedActivity.setState(RESUMED, "resumeTopActivityInnerLocked"); }Slog.i(TAG, "Restarting because process died: " + next); if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } elseif (SHOW_APP_STARTING_PREVIEW && lastFocusedStack != null && lastFocusedStack.isTopStackOnDisplay()) { next.showStartingWindow(null /* prev */, false /* newTask */, false /* taskSwitch */); } // 重要代码 mStackSupervisor.startSpecificActivityLocked(next, true, false); return true; }// ...省略部分代码} else { // Whoops, need to restart this activity! if (!next.hasBeenLaunched) { next.hasBeenLaunched = true; } else { if (SHOW_APP_STARTING_PREVIEW) { next.showStartingWindow(null /* prev */, false /* newTask */, false /* taskSwich */); } if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next); } if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next); // 重要代码 mStackSupervisor.startSpecificActivityLocked(next, true, true); } }

通过代码知道最后调用了ActivityStackSupervisor的startSpecificActivityLocked方法。
Activity启动源码分析-基于Android10(四)
【Activity启动源码分析-基于Android10(三)】参考文章:Activity的启动流程-基于Android10源码

    推荐阅读