Activity啓動流程總結-生命週期

前言

對於Activity的啓動流程,從事Android開發的同學都很熟悉。這裏僅結合自己的理解,通過博文梳理和記錄Activity啓動流程關鍵節點,便於記憶和將來回顧。

官方Activity生命週期示意圖:

activity-lifecycle

當 Activity A 啓動 Activity B 時,它們各自的生命週期回調順序是:

  1. Activity A 的 onPause() 方法執行。
  2. Activity B 的 onCreate()、onStart() 和 onResume() 方法依次執行。(Activity B 現在具有用戶焦點。)
  3. 然後,如果 Activity A 在屏幕上不再可見,則其 onStop() 方法執行。

大家對於這樣的結論都已熟知,但是ActivityManagerService是如何調度各Activity的生命回調,以及在什麼時機調度等問題,就需要進入Activity的啓動流程來找答案。

源碼探究

文中源碼基於Android 9.0

startActivity

首先通過activity.startActivity發起啓動Activity的請求指令,startActivity最終調用Instrumentation的execStartActivity方法:

[Instrumentation.java]

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    if (referrer != null) {
        intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    }
    // 省略ActivityMonitor相關部分
    // ···
    try {
        intent.migrateExtraStreamToClipData();
        intent.prepareToLeaveProcess(who);
        // 獲取IActivityManager binder通信接口,執行startActivity方法調用到AMS端
        int result = ActivityManager.getService()
            .startActivity(whoThread, who.getBasePackageName(), intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    token, target != null ? target.mEmbeddedID : null,
                    requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

該方法中通過IActivityManager.startActivity方法將指令和參數傳遞給ActivityManagerService,觸發ActivityManagerService對應的startActivity方法。

startActivityAsUser

ActivityManagerService的startActivity方法中又執行到startActivityAsUser方法:

[ActivityManagerService.java]

public final int 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("startActivity");

    // 根據uid檢查權限並返回修正後的uid
    userId = mActivityStartController.checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    // TODO: Switch to user app stacks here.
    // 獲取ActivityStarter(用於配置和執行啓動Activity),調用其execute方法執行啓動
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();
}

該方法中通過ActivityStarter保存啓動參數,然後執行啓動,execute方法中將調用startActivityMayWait方法。

startActivityMayWait

[ActivityStarter.java]

private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
        int userId, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {
    // Refuse possible leaked file descriptors
    if (intent != null && intent.hasFileDescriptors()) {
        throw new IllegalArgumentException("File descriptors passed in Intent");
    }
    mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
    // 標記intent有明確設置接收的組件
    boolean componentSpecified = intent.getComponent() != null;

    final int realCallingPid = Binder.getCallingPid();
    final int realCallingUid = Binder.getCallingUid();

    int callingPid;
    if (callingUid >= 0) {
        callingPid = -1;
    } else if (caller == null) {
        callingPid = realCallingPid;
        callingUid = realCallingUid;
    } else {
        callingPid = callingUid = -1;
    }
    
    // 創建intent的副本
    // Save a copy in case ephemeral needs it
    final Intent ephemeralIntent = new Intent(intent);
    // Don't modify the client's object!
    intent = new Intent(intent);
    // 省略攔截處理跳轉InstantAPP安裝相關部分 ···
    
    // 通過PackageManagerService查詢該intent是否有匹配的ResolveInfo
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId,
            0 /* matchFlags */,
                    computeResolveFilterUid(
                            callingUid, realCallingUid, mRequest.filterCallingUid));
    if (rInfo == null) {
        // 省略ResolveInfo未找到情況的處理部分
        // ···
    }
    // Collect information about the target of the Intent.
    // 獲取ResolveInfo中的ActivityInfo
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    
    synchronized (mService) {
        // 獲取處於焦點的ActivityStack
        final ActivityStack stack = mSupervisor.mFocusedStack;
        stack.mConfigWillChange = globalConfig != null
                && mService.getGlobalConfiguration().diff(globalConfig) != 0;
        if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
                "Starting activity when config will change = " + stack.mConfigWillChange);

        final long origId = Binder.clearCallingIdentity();
        
        // 省略heavy-weight進程處理部分 ···
        
        // 用來保存start Activity過程中創建或複用的ActivityRecord
        final ActivityRecord[] outRecord = new ActivityRecord[1];
        // 進一步執行啓動Activity
        int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
                voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
                callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
                ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
                allowPendingRemoteAnimationRegistryLookup);

        Binder.restoreCallingIdentity(origId);
        
        // 省略更新Configuration部分 ···
        
        // 省略對啓動結果outResult的處理部分,若存在需要等待目標Activity所在進程啓動
        // 或等待特定Activity可見等情況,則將阻塞等待喚醒再返回結果。
        // ···
    }
}

該方法中對intent做了檢查之後,調用startActivity方法進一步進行啓動流程,其中又調用另一個startActivity重載方法:

[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,
        SafeActivityOptions options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    // err記錄運行結果,默認記爲START_SUCCESS
    int err = ActivityManager.START_SUCCESS;
    // Pull the optional Ephemeral Installer-only bundle out of the options early.
    final Bundle verificationBundle
            = options != null ? options.popAppVerificationBundle() : null;
    
    // 調用端(即發起start請求的APP進程)對應的ProcessRecord
    ProcessRecord callerApp = null;
    if (caller != null) {
        // 從AMS中的緩存集合獲取
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            // 獲取調用端pid、uid
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            // 正常情況下,APP進程都會在AMS有一個ProcessRecord。若無,則認爲非法。
            Slog.w(TAG, "Unable to find app for caller " + caller
                    + " (pid=" + callingPid + ") when starting: "
                    + intent.toString());
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }
    
    // ActivityRecord對應表示Activity棧中的一個Activity
    // sourceRecord表示調用端Activity
    ActivityRecord sourceRecord = null;
    // resultRecord表示在onActivityResult接收結果的Activity
    ActivityRecord resultRecord = null;
    // resultTo表示調用端Activity的token,可通過它獲取Activity對應的ActivityRecord
    if (resultTo != null) {
        sourceRecord = mSupervisor.isInAnyStackLocked(resultTo);
        if (DEBUG_RESULTS) Slog.v(TAG_RESULTS,
                "Will send result to " + resultTo + " " + sourceRecord);
        if (sourceRecord != null) {
            if (requestCode >= 0 && !sourceRecord.finishing) {
                // 當需要回調onActivityResult的情況下,即調用startActivityForResult方法
                // requestCode參數大於0,resultRecord即爲sourceRecord
                resultRecord = sourceRecord;
            }
        }
    }
    
    // 獲取intent中設置的啓動標識
    final int launchFlags = intent.getFlags();

    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        // 省略處理FLAG_ACTIVITY_FORWARD_RESULT相關部分
        // ···
    }
    
    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;
    }
    
    // 省略檢查語音會話時啓動Activity部分,若目標Activity不支持VOICE類別,則標記
    // err = ActivityManager.START_NOT_VOICE_COMPATIBLE
    // ···
    
    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.getStack();

    // 若err標記爲失敗,則終止啓動
    if (err != START_SUCCESS) {
        if (resultRecord != null) {
            // 通知調用端onActivityResult,並傳回RESULT_CANCELED
            resultStack.sendActivityResultLocked(
                    -1, resultRecord, resultWho, requestCode, RESULT_CANCELED, null);
        }
        SafeActivityOptions.abort(options);
        return err;
    }
    
    // 檢查權限,若權限不通過則將abort標記爲true
    boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho,
            requestCode, callingPid, callingUid, callingPackage, ignoreTargetSecurity,
            inTask != null, callerApp, resultRecord, resultStack);
    abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
            callingPid, resolvedType, aInfo.applicationInfo);
            
    // 省略動畫選項設置相關部分 ···
    
    // 省略IActivityController部分,用於監聽攔截Activity啓動,可通過AMS.setActivityController
    // 設置監聽器,若攔截將標記abort=true。
    // 省略ActivityStartInterceptor部分 ···
    
    // 判斷是否終止
    if (abort) {
        if (resultRecord != null) {
            // 通知調用端onActivityResult,並傳回RESULT_CANCELED
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                    RESULT_CANCELED, null);
        }
        // We pretend to the caller that it was really started, but
        // they will just get a cancel result.
        ActivityOptions.abort(checkedOptions);
        return START_ABORTED;
    }
    
    // 省略權限檢查部分 ···
    // 省略臨時安裝APP部分 ···
    
    // 新建ActivityRecord,保存Activity啓動相關參數
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
            callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
            resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
            mSupervisor, checkedOptions, sourceRecord);
    if (outActivity != null) {
        outActivity[0] = r;
    }
    
    // 省略賦值AppTimeTracker部分 ···
    // 省略檢查是否允許應用切換部分 ···
    
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

該方法中對當前能否啓動目標Activity進行了各項檢查,並創建ActivityRecord用以保存Activity啓動信息,其中還有涉及Activity啓動攔截器的調用(若有設置)。最後調用了另一個重載方法startActivity,其中又調用startActivityUnchecked方法。

startActivityUnchecked

[ActivityStarter.java]

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {

    // 初始化ActivityStarter的成員變量,用當前啓動信息設置
    setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
            voiceInteractor);

    // 調整啓動標識
    computeLaunchingTaskFlags();

    // 獲取sourceRecord的ActivityStack,若調用端Activity即將finish,則修改啓動標識
    computeSourceStack();
    
    // 設置調整後的啓動標識
    mIntent.setFlags(mLaunchFlags);
    
    // 根據啓動標識和啓動模式檢查是否新建TASK或加入現有TASK。若加入現有TASK,則返回該TASK中可重用的ActivityRecord。
    ActivityRecord reusedActivity = getReusableIntentActivity();
    
    // 省略窗口模式相關部分 ···
    
    if (reusedActivity != null) {
        // 省略設置ActivityRecord和對應TaskRecord,根據啓動模式和啓動標識清理任務棧,
        // 觸發複用Activity的onNewIntent方法等等部分
        // ···
    }
    
    // 省略檢查packageName部分 ···
    // 省略當目標Activity與當前頂部Activity一致時,根據啓動標識和模式判斷是否不啓動新Activity以及對應的處理的相關部分
    
    // 省略設置TaskRecord部分
    
    // 省略權限設置
    // ···
    
    // 進行TaskRecord、APP Window Token、動畫、窗口複用等相關檢查和配置
    mTargetStack.startActivityLocked(mStartActivity, topFocused, newTask, mKeepCurTransition,
            mOptions);
    if (mDoResume) {
        final ActivityRecord topTaskActivity =
                mStartActivity.getTask().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(null, 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.
            mService.mWindowManager.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() && !mSupervisor.isFocusedStack(mTargetStack)) {
                mTargetStack.moveToFront("startActivityUnchecked");
            }
            // resumeFocusedStackTopActivityLocked方法進一步執行啓動操作
            mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                    mOptions);
        }
    } else if (mStartActivity != null) {
        // 加入最近任務列表
        mSupervisor.mRecentTasks.add(mStartActivity.getTask());
    }
    mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

    mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
            preferredLaunchDisplayId, mTargetStack);

    return START_SUCCESS;
}

該方法中會進行啓動標識和啓動模式檢查,判斷是否要複用的TaskRecord、ActivityRecord還是重新創建。若要新啓動一個Activity,則調用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,繼續進行啓動流程。

resumeFocusedStackTopActivityLocked

[ActivityStackSupervisor.java]

boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {

    if (!readyToResume()) {
        return false;
    }

    // 判斷目標Activity棧是否處於焦點,是的話則調用其resumeTopActivityUncheckedLocked方法進一步進行啓動流程
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }

    // ···

    return false;
}

該方法中主要對Activity棧的焦點進行檢查,之後便通過ActivityStack的resumeTopActivityUncheckedLocked繼續執行啓動流程。

resumeTopActivityUncheckedLocked

[ActivityStack.java]

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    // inResumeTopActivity標記當前處於resumeTopActivity過程中,用於避免重複遞歸調用。
    if (mStackSupervisor.inResumeTopActivity) {
        // Don't even start recursing.
        return false;
    }

    boolean result = false;
    try {
        // Protect against recursion.
        mStackSupervisor.inResumeTopActivity = true;
        // Activity啓動流程核心方法
        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 {
        mStackSupervisor.inResumeTopActivity = false;
    }

    return result;
}

該方法中調用了resumeTopActivityInnerLocked方法,resumeTopActivityInnerLocked方法中包含Activity切換調度的核心邏輯。

resumeTopActivityInnerLocked

啓動Activity的過程是將Activity置爲頂層可見,稱爲resume top Activity。resumeTopActivityInnerLocked方法中邏輯較多,因此拆解成多步來看。

1.pause當前顯示的Activity

[ActivityStack.java]

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    if (!mService.mBooting && !mService.mBooted) {
        // ActivityManagerService未啓動完成
        // Not ready yet!
        return false;
    }
    
    // Find the next top-most activity to resume in this stack that is not finishing and is
    // focusable. If it is not focusable, we will fall into the case below to resume the
    // top activity in the next focusable task.
    // 將要顯示的目標Activity
    final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
    
    final boolean hasRunningActivity = next != null;

    // TODO: Maybe this entire condition can get removed?
    // 判斷是否有ActivityDisplay
    if (hasRunningActivity && !isAttached()) {
        return false;
    }
    
    // 非頂部處於INITIALIZING狀態的Activity的AppWindowToken相關的清理動作
    mStackSupervisor.cancelInitializingActivities();
    
    // Remember how we'll process this pause/resume situation, and ensure
    // that the state is reset however we wind up proceeding.
    // 標記是否調用Activity的performUserLeaving回調方法
    boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;
    
    if (!hasRunningActivity) {
        // There are no activities left in the stack, let's look somewhere else.
        return resumeTopActivityInNextFocusableStack(prev, options, "noMoreActivities");
    }
    
    // 標記是否延遲顯示(AMS在特殊場景中會暫停APP切換)
    next.delayedResume = false;
    
    // 省略比較目標Activity是否已經是當前正在顯示的Activity、AMS暫時掛起、UserController判斷等部分
    // ···
    
    // The activity may be waiting for stop, but that is no longer
    // appropriate for it.
    // mStoppingActivities保存等待執行stop的Activity
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next);
    
    // 判斷當前是否存在暫停未完成的Activity
    // If we are currently pausing an activity, then don't do anything until that is done.
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                "resumeTopActivityLocked: Skip resume: some activity pausing.");
        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return false;
    }
    
    // 設置與wake lock關聯的WorkSource,用於應用耗電統計
    mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);
    
    // 省略畫中畫判斷部分 ···
    
    // pause非當前焦點的ActivityStack中的Activity(若有),將會調用ActivityStack的startPausingLocked方法
    // pausing標記是否有執行pause操作
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, false);
    // mResumedActivity表示當前正在顯示的Activity。例如Activity A啓動Activity B,
    // 則此時mResumedActivity即爲Activity A。
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        // mResumedActivity不爲空,pause這個Activity
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    if (pausing && !resumeWhilePausing) {
        // 前面執行了pause activity操作,且未設置FLAG_RESUME_WHILE_PAUSING標識
        // 省略更新mLruProcesses、設置畫中畫相關部分 ···
        return true;
    } else if (mResumedActivity == next && next.isState(RESUMED)
            && mStackSupervisor.allResumedActivitiesComplete()) {
        // 省略executeAppTransition部分 ···
        return true;
    }
    
    // 省略
    // ···
}

resumeTopActivityInnerLocked方法中第一部分首先會判斷當前是否能啓動目標Activity,其中比較重要的檢查點是判斷當前是否需要先執行pause Activity的操作。mResumedActivity記錄當前顯示的Activity,若它不爲空,則執行startPausingLocked方法,然後結束resumeTopActivityInnerLocked方法。

startPausingLocked

此時由Activity A啓動Activity B,則需要先pause Activity A,之後才resume Activity B。此處進入startPausingLocked方法,若其中成功執行pause操作,則會返回true,使resumeTopActivityInnerLocked退出執行。

[ActivityStack.java]

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    // mPausingActivity表示當前正在pause中的Activity,若存在,則先處理pause善後工作
    if (mPausingActivity != null) {
        Slog.wtf(TAG, "Going to pause when pause is already pending for " + mPausingActivity
                + " state=" + mPausingActivity.getState());
        if (!shouldSleepActivities()) {
            // Avoid recursion among check for sleep and complete pause during sleeping.
            // Because activity will be paused immediately after resume, just let pause
            // be completed by the order of activity paused from clients.
            completePauseLocked(false, resuming);
        }
    }
    // 將當前正在顯示的Activity賦值給prev,意味着它將被pause,成爲前一個Activity
    ActivityRecord prev = mResumedActivity;
    
    // 省略對prev的檢查部分 ···
    
    // prev賦值給mPausingActivity,此時mPausingActivity持有了當前顯示的Activity的ActivityRecord引用
    mPausingActivity = prev;
    mLastPausedActivity = prev;
    mLastNoHistoryActivity = (prev.intent.getFlags() & Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
            || (prev.info.flags & ActivityInfo.FLAG_NO_HISTORY) != 0 ? prev : null;
    // 設置prev狀態爲PAUSING,且會將mResumedActivity置爲null
    prev.setState(PAUSING, "startPausingLocked");
    // 更新prev所屬Task的最後活動時間
    prev.getTask().touchActiveTime();
    // 超時相關設置
    clearLaunchTime(prev);
    
    // ···
    
    // 判斷prev的IApplicationThread是否爲空,需要通過它向對應進程通信
    if (prev.app != null && prev.app.thread != null) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            // ···
            
            // 通知目標應用進程執行對應Activity的生命調度。
            mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,
                    PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
            // AMS調用Client不阻塞自身,因此發送完binder請求,就繼續往下執行。
        } catch (Exception e) {
            // Ignore exception, if process died other code will cleanup.
            Slog.w(TAG, "Exception thrown during pause", e);
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
    } else {
        mPausingActivity = null;
        mLastPausedActivity = null;
        mLastNoHistoryActivity = null;
    }
    
    // If we are not going to sleep, we want to ensure the device is
    // awake until the next activity is started.
    if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
        // 當前未進入休眠狀態,則向PowerManagerService申請wakelock使設備一直處於喚醒,並且設置超時消息。
        mStackSupervisor.acquireLaunchWakelock();
    }
    
    // 正常情況此時mPausingActivity仍持有引用
    if (mPausingActivity != null) {
        // Have the window manager pause its key dispatching until the new
        // activity has started.  If we're pausing the activity just because
        // the screen is being turned off and the UI is sleeping, don't interrupt
        // key dispatch; the same activity will pick it up again on wakeup.
        if (!uiSleeping) {
            // 暫停按鍵事件分發
            prev.pauseKeyDispatchingLocked();
        } else if (DEBUG_PAUSE) {
             Slog.v(TAG_PAUSE, "Key dispatch not paused for screen off");
        }

        // pauseImmediately默認false
        if (pauseImmediately) {
            // If the caller said they don't want to wait for the pause, then complete
            // the pause now.
            completePauseLocked(false, resuming);
            return false;

        } else {
            // 超時設置相關
            schedulePauseTimeout(prev);
            return true;
        }

    } else {
        // This activity failed to schedule the
        // pause, so just treat it as being paused now.
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Activity not running, resuming next.");
        // resuming默認持有下一個要顯示的ActivityRecord
        if (resuming == null) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked();
        }
        return false;
    }
}

該方法中將mResumedActivity賦值給mPausingActivity,並設置狀態爲PAUSING,再將mResumedActivity置爲null。之後通過IApplicationThread通知對應APP進程執行pause操作。

首先獲取PauseActivityItem對象,它繼承自ActivityLifecycleItem,表示請求調度Activity的哪個生命階段。
mService.getLifecycleManager獲取ClientLifecycleManager對象,它的作用是輔助分發,進入它的scheduleTransaction方法:

[ClientLifecycleManager.java]

void scheduleTransaction(@NonNull IApplicationThread client, @NonNull IBinder activityToken,
        @NonNull ActivityLifecycleItem stateRequest) throws RemoteException {
    // 創建ClientTransaction,保存client、activityToken、stateRequest參數
    final ClientTransaction clientTransaction = transactionWithState(client, activityToken,
            stateRequest);
    // 該方法中又調用ClientTransaction.schedule()
    scheduleTransaction(clientTransaction);
}

ClientTransaction事務對象,用於封裝命令和參數,發送到APP進程處理。ClientTransaction的schedule方法中又調用IApplicationThread的scheduleTransaction方法,並將ClientTransaction實例自身作爲入參調用。

scheduleTransaction

AMS通過IApplicationThread調用到APP進程,scheduleTransaction會觸發ApplicationThread.scheduleTransaction方法,該方法中又調用ActivityThread的父類ClientTransactionHandler的scheduleTransaction方法:

[ClientTransactionHandler.java]

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    // sendMessage由ActivityThread實現
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

sendMessage是抽象方法由ActivityThread實現,其中又調用另一個sendMessage重載方法:
[ActivityThread.java]

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) Slog.v(
        TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
        + ": " + arg1 + " / " + obj);
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    // async默認爲false
    if (async) {
        msg.setAsynchronous(true);
    }
    // 當前處於binder線程,通過mH切換到主線程執行
    mH.sendMessage(msg);
}

該方法中利用mH從binder線程切換到主線程來處理這個事務。在mH的handleMessage方法中的對應case EXECUTE_TRANSACTION中,又通過TransactionExecutor的execute方法來執行ClientTransaction事務消息。

[TransactionExecutor.java]

public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    // 遍歷調用ClientTransaction中的mActivityCallbacks成員
    executeCallbacks(transaction);

    // 調用ClientTransaction中的mLifecycleStateRequest成員,即在AMS中設置的PauseActivityItem
    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}

在executeLifecycleState中,會先後調用PauseActivityItem的executepostExecute方法。其中execute會調用ClientTransactionHandler.handlePauseActivity方法,handlePauseActivity由ActivityThread實現。

handlePauseActivity

[ActivityThread.java]

@Override
public void C(IBinder token, boolean finished, boolean userLeaving,
        int configChanges, PendingTransactionActions pendingActions, String reason) {
    // mActivities保存應用進程的Activity信息,利用token作爲key(IBinder除了用於進程間通信,也可用作Key標識)
    // ActivityClientRecord的作用同ActivityRecord,表示APP進程中的Activity信息,
    // 而ActivityRecord表示在AMS中記錄的Activity信息。
    ActivityClientRecord r = mActivities.get(token);
    if (r != null) {
        if (userLeaving) {
            // 觸發onUserInteraction()和onUserLeaveHint()
            performUserLeavingActivity(r);
        }

        r.activity.mConfigChangeFlags |= configChanges;
        // 執行pause PauseActivity的操作
        performPauseActivity(r, finished, reason, pendingActions);

        // Make sure any pending writes are now committed.
        if (r.isPreHoneycomb()) {
            QueuedWork.waitToFinish();
        }
        mSomeActivitiesChanged = true;
    }
}

performPauseActivity方法中會對ActivityClientRecord中保存的狀態進行檢查,並視情況調用onSaveInstanceState(),之後又調用performPauseActivityIfNeeded方法:

[ActivityThread.java]

private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    if (r.paused) {
        // You are already paused silly...
        return;
    }

    try {
        r.activity.mCalled = false;
        // 調用onPause()生命週期回調
        mInstrumentation.callActivityOnPause(r.activity);
        if (!r.activity.mCalled) {
            throw new SuperNotCalledException("Activity " + safeToComponentShortString(r.intent)
                    + " did not call through to super.onPause()");
        }
    } catch (SuperNotCalledException e) {
        throw e;
    } catch (Exception e) {
        if (!mInstrumentation.onException(r.activity, e)) {
            throw new RuntimeException("Unable to pause activity "
                    + safeToComponentShortString(r.intent) + ": " + e.toString(), e);
        }
    }
    // 設置ActivityClientRecord的狀態爲ON_PAUSE
    r.setState(ON_PAUSE);
}

在該方法中通過Instrumentation最終觸發了Activity的onPause生命週期回調方法。

當完成了這些操作後,接着將執行PauseActivityItem的postExecute方法:
[PauseActivityItem.java]

@Override
public void postExecute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    if (mDontReport) {
        return;
    }
    try {
        // TODO(lifecycler): Use interface callback instead of AMS.
        // 通知AMS,pause Activity完成
        ActivityManager.getService().activityPaused(token);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
}

該方法中將調用AMS的activityPaused,再通知回AMS,Activity pause完成。

activityPaused

[ActivityManagerService.java]

@Override
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        // 通過token查找ActivityStack
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            // activityPausedLocked中又會調用completePauseLocked方法
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}
completePauseLocked

該方法中將調用ActivityStack的completePauseLocked方法,參數傳入truenull

[ActivityStack.java]

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    // 將之前AMS保存的進程pause中的Activity賦值給prev
    ActivityRecord prev = mPausingActivity;
    
    if (prev != null) {
        prev.setWillCloseOrEnterPip(false);
        final boolean wasStopping = prev.isState(STOPPING);
        prev.setState(PAUSED, "completePausedLocked");
        if (prev.finishing) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Executing finish of activity: " + prev);
            // finish Activity操作
            prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE, false,
                    "completedPausedLocked");
        } else if (prev.app != null) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev
                    + " wasStopping=" + wasStopping + " visible=" + prev.visible);
            if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) {
                if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE,
                        "Complete pause, no longer waiting: " + prev);
            }
            if (prev.deferRelaunchUntilPaused) {
                // Complete the deferred relaunch that was waiting for pause to complete.
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev);
                prev.relaunchActivityLocked(false /* andResume */,
                        prev.preserveWindowOnDeferredRelaunch);
            } else if (wasStopping) {
                // We are also stopping, the stop request must have gone soon after the pause.
                // We can't clobber it, because the stop confirmation will not be handled.
                // We don't need to schedule another stop, we only need to let it happen.
                prev.setState(STOPPING, "completePausedLocked");
            } else if (!prev.visible || shouldSleepOrShutDownActivities()) {
                // Clear out any deferred client hide we might currently have.
                prev.setDeferHidingClient(false);
                // If we were visible then resumeTopActivities will release resources before
                // stopping.
                // 添加到ActivityStackSupervisor的mStoppingActivities集合中,
                // 等待後續執行stop Activity操作,並且發送一個IDLE消息。
                addToStopping(prev, true /* scheduleIdle */, false /* idleDelayed */);
            }
        } else {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "App died during pause, not stopping: " + prev);
            prev = null;
        }
        // It is possible the activity was freezing the screen before it was paused.
        // In that case go ahead and remove the freeze this activity has on the screen
        // since it is no longer visible.
        if (prev != null) {
            // 停止屏幕凍結
            prev.stopFreezingScreenLocked(true /*force*/);
        }
        // 取消mPausingActivity引用,表示沒有Pausing Activity
        mPausingActivity = null;
    }
    
    // 此時resumeNext值爲true,表示要調度resume下一個Activity
    if (resumeNext) {
        final ActivityStack topStack = mStackSupervisor.getFocusedStack();
        // 判斷焦點ActivityStack是否不準備休眠、掛起
        if (!topStack.shouldSleepOrShutDownActivities()) {
            mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
        } else {
            checkReadyForSleep();
            ActivityRecord top = topStack.topRunningActivityLocked();
            if (top == null || (prev != null && top != prev)) {
                // If there are no more activities available to run, do resume anyway to start
                // something. Also if the top activity on the stack is not the just paused
                // activity, we need to go ahead and resume it to ensure we complete an
                // in-flight app switch.
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            }
        }
    }
    
    // 省略 ···
    
    // 檢查更新所有Activity的可見和配置
    mStackSupervisor.ensureActivitiesVisibleLocked(resuming, 0, !PRESERVE_WINDOWS);
}

completePauseLocked方法中會將這次pause的ActivityRecord存入ActivityStackSupervisor的mStoppingActivities成員(ArrayList)中,用於後續再對其執行stop和finish操作。之後將mPausingActivity賦值爲null,表示當前沒有正在pause的Activity。接着便又調用了resumeFocusedStackTopActivityLocked方法,再次進行resume Activity。

2.判斷APP進程是否存在

resumeFocusedStackTopActivityLocked會經過層層調用,回到resumeTopActivityInnerLocked方法中。

回到前面的resumeTopActivityInnerLocked介紹中,此時判斷mResumedActivity已經爲null(在startPausingLocked中會置爲null),因此不進行pause操作,繼續往下執行:

[ActivityStack.java]

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // 省略1部分
    // ···
    
    // 省略mLastNoHistoryActivity因休眠而未執行finish的處理部分
    // 省略上一個Activity(即剛剛pause的)的窗口隱藏相關部分
    // ···
    // 省略和WindowManagerService交互、過渡動畫相關部分 ···

    // 獲取上一個焦點ActivityStack
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    // next表示將要顯示的Activity,判斷對應APP進程是否存在。
    // 通過緩存的ProcessRecord中的IApplicationThread是否存在來判斷,因爲需要通過它向APP進程通信。
    if (next.app != null && next.app.thread != null) {
        // If the previous activity is translucent, force a visibility update of
        // the next activity, so that it's added to WM's opening app list, and
        // transition animation can be set up properly.
        // For example, pressing Home button with a translucent activity in focus.
        // Launcher is already visible in this case. If we don't add it to opening
        // apps, maybeUpdateTransitToWallpaper() will fail to identify this as a
        // TRANSIT_WALLPAPER_OPEN animation, and run some funny animation.
        final boolean lastActivityTranslucent = lastStack != null
                && (lastStack.inMultiWindowMode()
                || (lastStack.mLastPausedActivity != null
                && !lastStack.mLastPausedActivity.fullscreen));
        
        // The contained logic must be synchronized, since we are both changing the visibility
        // and updating the {@link Configuration}. {@link ActivityRecord#setVisibility} will
        // ultimately cause the client code to schedule a layout. Since layouts retrieve the
        // current {@link Configuration}, we must ensure that the below code updates it before
        // the layout can occur.
        synchronized(mWindowManager.getWindowManagerLock()) {
            // This activity is now becoming visible.
            if (!next.visible || next.stopped || lastActivityTranslucent) {
                next.setVisibility(true);
            }

            // schedule launch ticks to collect information about slow apps.
            next.startLaunchTickingLocked();

            ActivityRecord lastResumedActivity =
                    lastStack == null ? null :lastStack.mResumedActivity;
            final ActivityState lastState = next.getState();

            mService.updateCpuStats();

            if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + next
                    + " (in existing)");

            next.setState(RESUMED, "resumeTopActivityInnerLocked");

            mService.updateLruProcessLocked(next.app, true, null);
            updateLRUListLocked(next);
            mService.updateOomAdjLocked();
            
            // 省略 ···
            
            try {
                // 事務對象,用於封裝命令和參數,發送到APP進程處理
                final ClientTransaction transaction = ClientTransaction.obtain(next.app.thread,
                        next.appToken);
                // 省略分發pending results和給ClientTransaction添加Callback部分
                // ···

                next.sleeping = false;
                mService.getAppWarningsLocked().onResumeActivity(next);
                mService.showAskCompatModeDialogLocked(next);
                next.app.pendingUiClean = true;
                next.app.forceProcessStateUpTo(mService.mTopProcessState);
                next.clearOptionsLocked();
                // 設置ResumeActivityItem生命週期執行請求
                transaction.setLifecycleStateRequest(
                        ResumeActivityItem.obtain(next.app.repProcState,
                                mService.isNextTransitionForward()));
               // 調度到APP進程
               mService.getLifecycleManager().scheduleTransaction(transaction);

                if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Resumed "
                        + next);
            } 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;
                } else  if (SHOW_APP_STARTING_PREVIEW && lastStack != null
                        && lastStack.isTopStackOnDisplay()) {
                    next.showStartingWindow(null /* prev */, false /* newTask */,
                            false /* taskSwitch */);
                }
                // 上面執行發送異常,執行startSpecificActivityLocked方法
                mStackSupervisor.startSpecificActivityLocked(next, true, false);
                if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
                return true;
            }
        }
        
        // 上面resume Activity階段未發生異常會執行到這裏
        // From this point on, if something goes wrong there is no way
        // to recover the activity.
        try {
            // 進行resume操作的善後工作
            next.completeResumeLocked();
        } catch (Exception e) {
            // If any exception gets thrown, toss away this
            // activity and try the next one.
            Slog.w(TAG, "Exception thrown during resume of " + next, e);
            // 發生異常的話就finish該Activity
            requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                    "resume-exception", true);
            if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
            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);
        // APP進程不存在或無效,執行startSpecificActivityLocked
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
    
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    return true;
}

resumeTopActivityInnerLocked方法的下半部分中,判斷如果Activity所在進程存在且Activity之前啓動過,則直接發送ResumeActivityItem請求通知APP進程進行resume,否則調用ActivityStackSupervisorstartSpecificActivityLocked方法繼續執行。

startSpecificActivityLocked

[ActivityStackSupervisor.java]

void startSpecificActivityLocked(ActivityRecord r,
        boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    // 查找目標Activity對應的進程信息
    ProcessRecord app = mService.getProcessRecordLocked(r.processName,
            r.info.applicationInfo.uid, true);

    getLaunchTimeTracker().setLaunchTime(r);

    // 判斷目標進程是否存在且有效
    if (app != null && app.thread != null) {
        try {
            if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                    || !"android".equals(r.info.packageName)) {
                // Don't add this if it is a platform component that is marked
                // to run in multiple processes, because this is actually
                // part of the framework so doesn't make sense to track as a
                // separate apk in the process.
                app.addPackage(r.info.packageName, r.info.applicationInfo.longVersionCode,
                        mService.mProcessStats);
            }
            realStartActivityLocked(r, app, 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.
    }

    // 啓動目標進程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

該方法中判斷目標APP進程若存在,則調用realStartActivityLocked方法繼續進行啓動流程,否則調用startProcessLocked方法先啓動目標進程。

啓動目標APP進程

startProcessLocked方法又調用另一個重載方法:

[ActivityManagerService.java]

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    long startTime = SystemClock.elapsedRealtime();
    ProcessRecord app;
    
    // 省略bad process相關部分 ···
    // 省略再次判斷進程已存在或正在啓動相關部分 ···
    
    if (app == null) {
        checkTime(startTime, "startProcess: creating new process record");
        // 創建ProcessRecord實例,並將它添加入AMS.mProcessNames中保存
        app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
        if (app == null) {
            Slog.w(TAG, "Failed making new process record for "
                    + processName + "/" + info.uid + " isolated=" + isolated);
            return null;
        }
        app.crashHandler = crashHandler;
        app.isolatedEntryPoint = entryPoint;
        app.isolatedEntryPointArgs = entryPointArgs;
        checkTime(startTime, "startProcess: done creating new process record");
    } else {
        // If this is a new package in the process, add the package to the list
        app.addPackage(info.packageName, info.versionCode, mProcessStats);
        checkTime(startTime, "startProcess: added package to existing proc");
    }
    
    // 省略系統未就緒情況的部分 ···
    
    checkTime(startTime, "startProcess: stepping in to startProcess");
    // 調用另一個重載方法進一步執行啓動進程
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    checkTime(startTime, "startProcess: done starting proc!");
    return success ? app : null;
}

該方法中在進一步調用啓動進程前,會先創建ProcessRecord,並保存在AMS的mProcessNames成員中。

startProcessLocked方法中生成startSeqProcessRecord綁定保存,用於檢查啓動的進程和ProcessRecord是否對應。之後又會經過層層調用,最終通過Process.start請求ZYGOTE創建子APP進程。

APP進程創建和初始化的流程就如《Activity啓動流程總結-ActivityThread》,當APP進程創建後會調用AMS的attachApplication方法通知進程啓動完成。

APP進程啓動完成

[ActivityManagerService.java]

private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    // ···
    try {
        // 執行ActivityStackSupervisor的attachApplicationLocked方法
        if (mStackSupervisor.attachApplicationLocked(app)) {
            didSomething = true;
        }
    } catch (Exception e) {
        Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
        badApp = true;
    }
    // ···
}

[ActivityStackSupervisor.java]

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
    // didSomething標記是否有啓動組件
    boolean didSomething = false;
    // 遍歷ActivityDisplay(一個ActivityDisplay對應一個顯示屏幕)
    for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
        final ActivityDisplay display = mActivityDisplays.valueAt(displayNdx);
        for (int stackNdx = display.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
            final ActivityStack stack = display.getChildAt(stackNdx);
            if (!isFocusedStack(stack)) {
                continue;
            }
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        // 調用realStartActivityLocked方法啓動待resume的Activity
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Exception in new application when starting activity "
                                + top.intent.getComponent().flattenToShortString(), e);
                        throw e;
                    }
                }
            }
        }
    }
    if (!didSomething) {
        ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }
    return didSomething;
}

可以看出AMS在收到APP進程啓動完成後,會調用realStartActivityLocked啓動因爲等待目標進程啓動而暫緩的Activity。

realStartActivityLocked

[ActivityStackSupervisor.java]

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
        boolean andResume, boolean checkConfig) throws RemoteException {
    // 檢查是否存在pausing中的Activity
    if (!allPausedActivitiesComplete()) {
        // While there are activities pausing we skipping starting any new activities until
        // pauses are complete. NOTE: that we also do this for activities that are starting in
        // the paused state because they will first be resumed then paused on the client side.
        if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                "realStartActivityLocked: Skipping start of r=" + r
                + " some activities pausing...");
        return false;
    }
    
    final TaskRecord task = r.getTask();
    final ActivityStack stack = task.getStack();

    beginDeferResume();
    
    try {
        // ···
        int idx = app.activities.indexOf(r);
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();
        // ···
        try {
            // ···
            
            // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
                    r.appToken);
            // 創建LaunchActivityItem並添加至mActivityCallbacks成員保存
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, mService.isNextTransitionForward(),
                    profilerInfo));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            // 此時andResume爲true,設置ResumeActivityItem爲Activity最終期望的狀態
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            // 設置給mLifecycleStateRequest成員
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            // 調用給APP進程
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            
            // 省略heavy-weight process相關處理部分 ···
        } catch (RemoteException e) {
            if (r.launchFailed) {
                // This is the second time we failed -- finish activity
                // and give up.
                Slog.e(TAG, "Second failure launching "
                        + r.intent.getComponent().flattenToShortString()
                        + ", giving up", e);
                mService.appDiedLocked(app);
                stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                        "2nd-crash", false);
                return false;
            }

            // This is the first time we failed -- restart process and
            // retry.
            r.launchFailed = true;
            app.activities.remove(r);
            throw e;
        }
    } finally {
        endDeferResume();
    }
    
    r.launchFailed = false;
    if (stack.updateLRUListLocked(r)) {
        Slog.w(TAG, "Activity " + r + " being launched, but already in LRU list");
    }

    // TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
    // so updating the state should be done accordingly.
    if (andResume && readyToResume()) {
        // As part of the process of launching, ActivityThread also performs
        // a resume.
        // 更新ActivityRecord的狀態,以及發送超時消息等操作
        stack.minimalResumeActivityLocked(r);
    } else {
        // This activity is not starting in the resumed state... which should look like we asked
        // it to pause+stop (but remain visible), and it has done so and reported back the
        // current icicle and other state.
        if (DEBUG_STATES) Slog.v(TAG_STATES,
                "Moving to PAUSED: " + r + " (starting in paused state)");
        r.setState(PAUSED, "realStartActivityLocked");
    }

    // Launch the new version setup screen if needed.  We do this -after-
    // launching the initial activity (that is, home), so that it can have
    // a chance to initialize itself while in the background, making the
    // switch back to it faster and look better.
    if (isFocusedStack(stack)) {
        mService.getActivityStartController().startSetupActivity();
    }

    // Update any services we are bound to that might care about whether
    // their client may have activities.
    if (r.app != null) {
        mService.mServices.updateServiceConnectionActivitiesLocked(r.app);
    }

    return true;
}

該方法中創建ClientTransaction對象,先後添加LaunchActivityItemResumeActivityItem兩個子項,併發送給APP進程執行相應事務處理。

這個發送接收過程在pause Activity階段介紹過,最終將在APP進程中調用TransactionExecutor的execute方法,在execute中先遍歷處理ClientTransaction的mActivityCallbacks成員,之後處理mLifecycleStateRequest成員。

LaunchActivityItem的處理

這裏會先處理LaunchActivityItem,調用它的execute方法,execute中會創建ActivityClientRecord對象,然後調用ActivityThread的handleLaunchActivity方法並傳入ActivityClientRecord:

handleLaunchActivity

[ActivityThread.java]

public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    // 移除GC閒時消息
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // 省略性能監控相關 ···

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    if (!ThreadedRenderer.sRendererDisabled) {
        GraphicsEnvironment.earlyInitEGL();
    }
    // 初始化WindowManagerGlobal
    WindowManagerGlobal.initialize();

    // 執行啓動Activity,並返回Activity實例
    final Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        if (!r.activity.mFinished && pendingActions != null) {
            pendingActions.setOldState(r.state);
            pendingActions.setRestoreInstanceState(true);
            pendingActions.setCallOnPostCreate(true);
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            // 啓動Activity期間發生錯誤,請求AMS關閉該Activity
            ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }

    return a;
}

performLaunchActivity

[ActivityThread.java]

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    // 獲取LoadedApk對象
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    // 獲取ComponentName
    ComponentName component = r.intent.getComponent();
    if (component == null) {
        // intent中未顯式設置,從PackageManagerService中查找匹配的ResolveInfo構建ComponentName
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) {
        // 若Activity設置了別名(即targetActivity屬性),則使用targetActivity構建ComponentName
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }
    
    // 獲取ContextImpl實例
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 獲取反射實例化Activity
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
    
    try {
        // 獲取LoadedApk中緩存的Application對象(在APP進程啓動時實例化)
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        // ···

        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            // 將activity賦值給ContextImpl的mOuterContext成員,使ContextImpl持有activity引用
            appContext.setOuterContext(activity);
            // 進行Activity的成員賦值和初始化等操作
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window, r.configCallback);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                // 設置主題
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) {
                // 設置了persistable模式,將觸發兩個參數的onCreate生命週期回調方法
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                // 觸發帶一個入參的onCreate生命週期回調方法
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
        }
        // 更新ActivityClientRecord中的狀態
        r.setState(ON_CREATE);

        // 保存ActivityClientRecord
        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}

該方法中先後實例化ContextImplActivity,並設置互相間的綁定關係,最後觸發onCreate生命週期回調。當執行完這一切後,ActivityClientRecord中mLifecycleState成員(生命週期狀態)被設置爲ON_CREATE

ContextImpl的創建

這裏先看下如何獲取和實例化ContextImpl,在createBaseContextForActivity方法中通過ContextImpl.createActivityContext獲取ContextImpl實例:
[ContextImpl.java]

static ContextImpl createActivityContext(ActivityThread mainThread,
        LoadedApk packageInfo, ActivityInfo activityInfo, IBinder activityToken, int displayId,
        Configuration overrideConfiguration) {
    if (packageInfo == null) throw new IllegalArgumentException("packageInfo");

    // 省略split apk部分 ···

    // 實例化ContextImpl,並初始化相關成員
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo, activityInfo.splitName,
            activityToken, null, 0, classLoader);

    // Clamp display ID to DEFAULT_DISPLAY if it is INVALID_DISPLAY.
    displayId = (displayId != Display.INVALID_DISPLAY) ? displayId : Display.DEFAULT_DISPLAY;

    final CompatibilityInfo compatInfo = (displayId == Display.DEFAULT_DISPLAY)
            ? packageInfo.getCompatibilityInfo()
            : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;

    // 獲取ResourcesManager單例對象
    final ResourcesManager resourcesManager = ResourcesManager.getInstance();

    // Create the base resources for which all configuration contexts for this Activity
    // will be rebased upon.
    // 初始化mResources成員
    context.setResources(resourcesManager.createBaseActivityResources(activityToken,
            packageInfo.getResDir(),
            splitDirs,
            packageInfo.getOverlayDirs(),
            packageInfo.getApplicationInfo().sharedLibraryFiles,
            displayId,
            overrideConfiguration,
            compatInfo,
            classLoader));
    context.mDisplay = resourcesManager.getAdjustedDisplay(displayId,
            context.getResources());
    return context;
}
Activity的attach

[Activity.java]

final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback) {
    attachBaseContext(context);

    // Fragment相關初始化
    mFragments.attachHost(null /*parent*/);
 
    // 初始化PhoneWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    // 指定當前運行線程爲UiThread
    mUiThread = Thread.currentThread();

    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    // 語音交互相關
    if (voiceInteractor != null) {
        if (lastNonConfigurationInstances != null) {
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
        } else {
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        }
    }

    // 獲取WindowManagerService
    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        // 設置窗口顯示容器
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;

    mWindow.setColorMode(info.colorMode);

    setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
    enableAutofillCompatibilityIfNeeded();
}

ResumeActivityItem的處理

在LaunchActivityItem處理完後,便輪到了ResumeActivityItem。

進入TransactionExecutor的executeLifecycleState方法:
[TransactionExecutor.java]

private void executeLifecycleState(ClientTransaction transaction) {
    // 此時的lifecycleItem爲ResumeActivityItem
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    if (lifecycleItem == null) {
        // No lifecycle request, return early.
        return;
    }
    log("Resolving lifecycle state: " + lifecycleItem);

    final IBinder token = transaction.getActivityToken();
    // 根據token取出緩存的ActivityClientRecord
    final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

    if (r == null) {
        // Ignore requests for non-existent client records for now.
        return;
    }

    // Cycle to the state right before the final requested state.
    // 該方法中會按生命週期順序補充執行對應生命週期階段的方法
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */);

    // Execute the final transition with proper parameters.
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}

經過上面performLaunchActivity方法的處理,此時Activity的狀態爲ON_CREATE,但是ResumeActivityItem中保存的期望狀態是ON_RESUME,在cycleToPath方法中會先調用handleStartActivity方法,進行Activity start階段的處理。

handleStartActivity

[ActivityThread.java]

public void handleStartActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions) {
    final Activity activity = r.activity;
    // 狀態檢查
    if (r.activity == null) {
        // TODO(lifecycler): What do we do in this case?
        return;
    }
    if (!r.stopped) {
        throw new IllegalStateException("Can't start activity that is not stopped.");
    }
    if (r.activity.mFinished) {
        // TODO(lifecycler): How can this happen?
        return;
    }

    // Start
    // performStart方法中會通過Instrumentation調用Activity的onStart生命週期回調方法
    activity.performStart("handleStartActivity");
    // 設置生命週期狀態爲ON_START
    r.setState(ON_START);

    if (pendingActions == null) {
        // No more work to do.
        return;
    }

    // Restore instance state
    if (pendingActions.shouldRestoreInstanceState()) {
        // 將回調onRestoreInstanceState生命週期方法
        if (r.isPersistable()) {
            if (r.state != null || r.persistentState != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                        r.persistentState);
            }
        } else if (r.state != null) {
            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
        }
    }

    // Call postOnCreate()
    if (pendingActions.shouldCallOnPostCreate()) {
        activity.mCalled = false;
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnPostCreate(activity, r.state,
                    r.persistentState);
        } else {
            mInstrumentation.callActivityOnPostCreate(activity, r.state);
        }
        if (!activity.mCalled) {
            throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString()
                            + " did not call through to super.onPostCreate()");
        }
    }
}

該方法中調用了onStart生命週期方法,並將Activity生命週期狀態設置爲ON_START。

handleResumeActivity

接下來執行ResumeActivityItem的execute方法,其中又調用handleResumeActivity方法:

[ActivityThread.java]

public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
        String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;
    
    // TODO Push resumeArgs into the activity for consideration
    // 該方法中首先視情況調用onRestart生命週期回調方法,接着調用onResume生命週期方法,
    // 設置狀態爲ON_RESUME,最後返回緩存的ActivityClientRecord。
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    if (r == null) {
        // We didn't actually resume the activity, so skipping any follow-up actions.
        return;
    }
    
    // 省略初始化DecorView、ViewRootImpl、向WindowManagerService註冊窗口等操作部分
    // ···
    
    r.nextIdle = mNewActivities;
    mNewActivities = r;
    // 往當前線程添加一個閒時消息
    Looper.myQueue().addIdleHandler(new Idler());
}

該方法中將回調onResume生命週期方法,並設置生命週期狀態爲ON_RESUME。如果當前Activity是首次啓動,則還需要進行DecorView、ViewRootImpl、WindowManager相關初始化操作,向WindowManagerService註冊窗口,設置視圖樹可見。
在該方法下半部分的源碼中(此處省略)可以得知,Activity首次啓動的時候是在onResume後才真正可見,並不是onStart時就部分可見。

該方法最後,往當前線程Looper中的消息隊列中添加一個閒時消息Idler,當消息隊列中無消息處理時將回調它的queueIdle方法,在queueIdle中又會通過IActivityManager調用AMS的activityIdle方法

activityIdle

APP進程通過activityIdle方法通知AMS目標Activity的resume操作完成,其中會根據token取得對應的ActivityStack,調用它的activityIdleInternalLocked方法:
[ActivityStackSupervisor.java]

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
        boolean processPausingActivities, Configuration config) {
    if (DEBUG_ALL) Slog.v(TAG, "Activity idle: " + token);

    ArrayList<ActivityRecord> finishes = null;
    ArrayList<UserState> startingUsers = null;
    int NS = 0;
    int NF = 0;
    boolean booting = false;
    boolean activityRemoved = false;
    
    ActivityRecord r = ActivityRecord.forTokenLocked(token);
    if (r != null) {
        // 移除超時消息
        mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
        // 省略
        // ···
        r.idle = true;
    }
    
    // 省略檢查resumedActivity的idle相關部分 ···
    
    // Atomically retrieve all of the other things to do.
    // 獲取paused的ActivityRecord集合(Activity pause後會加入mStoppingActivities保存)
    final ArrayList<ActivityRecord> stops = processStoppingActivitiesLocked(r,
            true /* remove */, processPausingActivities);
    NS = stops != null ? stops.size() : 0;
    if ((NF = mFinishingActivities.size()) > 0) {
        // mFinishingActivities保存已經stop,等待finish的ActivityRecord
        finishes = new ArrayList<>(mFinishingActivities);
        mFinishingActivities.clear();
    }
    // 省略 ···
    
    // Stop any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NS; i++) {
        // 依次取出ActivityRecord,對其執行stop或finish操作
        r = stops.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            // 
            if (r.finishing) {
                stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false,
                        "activityIdleInternalLocked");
            } else {
                stack.stopActivityLocked(r);
            }
        }
    }
    
    // Finish any activities that are scheduled to do so but have been
    // waiting for the next one to start.
    for (int i = 0; i < NF; i++) {
        r = finishes.get(i);
        final ActivityStack stack = r.getStack();
        if (stack != null) {
            // 銷燬APP進程中的Activity實例
            activityRemoved |= stack.destroyActivityLocked(r, true, "finish-idle");
        }
    }
    
    // 省略 ···
    
    mService.trimApplications();
    //dump();
    //mWindowManager.dump();

    if (activityRemoved) {
        resumeFocusedStackTopActivityLocked();
    }

    return r;
}

該方法中獲取之前保存的等待stop或finish的ActivityRecord,執行相應的操作。

stopActivityLocked

[ActivityStack.java]

final void stopActivityLocked(ActivityRecord r) {
    // 省略FLAG_ACTIVITY_NO_HISTORY、FLAG_NO_HISTORY相關部分 ···
    if (r.app != null && r.app.thread != null) {
        adjustFocusedActivityStack(r, "stopActivity");
        r.resumeKeyDispatchingLocked();
        try {
            r.stopped = false;
            if (DEBUG_STATES) Slog.v(TAG_STATES,
                    "Moving to STOPPING: " + r + " (stop requested)");
            r.setState(STOPPING, "stopActivityLocked");
            if (DEBUG_VISIBILITY) Slog.v(TAG_VISIBILITY,
                    "Stopping visible=" + r.visible + " for " + r);
            if (!r.visible) {
                r.setVisible(false);
            }
            EventLogTags.writeAmStopActivity(
                    r.userId, System.identityHashCode(r), r.shortComponentName);
            // 使用StopActivityItem封裝事務,調度到APP進程
            mService.getLifecycleManager().scheduleTransaction(r.app.thread, r.appToken,
                    StopActivityItem.obtain(r.visible, r.configChangeFlags));
            if (shouldSleepOrShutDownActivities()) {
                r.setSleeping(true);
            }
            // 發送超時消息
            Message msg = mHandler.obtainMessage(STOP_TIMEOUT_MSG, r);
            mHandler.sendMessageDelayed(msg, STOP_TIMEOUT);
        } catch (Exception e) {
            // Maybe just ignore exceptions here...  if the process
            // has crashed, our death notification will clean things
            // up.
            Slog.w(TAG, "Exception thrown during pause", e);
            // Just in case, assume it to be stopped.
            r.stopped = true;
            if (DEBUG_STATES) Slog.v(TAG_STATES, "Stop failed; moving to STOPPED: " + r);
            r.setState(STOPPED, "stopActivityLocked");
            if (r.deferRelaunchUntilPaused) {
                destroyActivityLocked(r, true, "stop-except");
            }
        }
    }
}

handleStopActivity

stopActivityLocked方法中發送ClientTransaction到對應APP進程(之前pause的Activity所在進程),然後調用StopActivityItem的execute方法,其中將調用ActivityThread的handleStopActivity方法:

[ActivityThread.java]

public void handleStopActivity(IBinder token, boolean show, int configChanges,
        PendingTransactionActions pendingActions, boolean finalStateRequest, String reason) {
    // 通過token查找ActivityClientRecord(之前pause的Activity)
    final ActivityClientRecord r = mActivities.get(token);
    r.activity.mConfigChangeFlags |= configChanges;

    // 繼承自Runnable,用於保存stop相關參數和通知AMS結果
    final StopInfo stopInfo = new StopInfo();
    // 將調用onStop生命週期回調方法,設置狀態爲ON_STOP,視情況調用onSaveInstanceState回調方法
    performStopActivityInner(r, stopInfo, show, true /* saveState */, finalStateRequest,
            reason);

    if (localLOGV) Slog.v(
        TAG, "Finishing stop of " + r + ": show=" + show
        + " win=" + r.window);

    updateVisibility(r, show);

    // Make sure any pending writes are now committed.
    if (!r.isPreHoneycomb()) {
        QueuedWork.waitToFinish();
    }

    stopInfo.setActivity(r);
    stopInfo.setState(r.state);
    stopInfo.setPersistentState(r.persistentState);
    // 將stopInfo添加至pendingActions保存
    pendingActions.setStopInfo(stopInfo);
    mSomeActivitiesChanged = true;
}

該方法中創建StopInfo保存stop過程相關參數,接着調用performStopActivityInner方法,在其中會調用onStop生命週期回調方法,設置狀態爲ON_STOP,視情況調用onSaveInstanceState回調方法。方法最後將stopInfo添加進pendingActions保存。

reportStop

StopActivityItem在執行完execute方法後,會執行postExecute方法,而在這個方法中會調用ActivityThread的reportStop方法:
[ActivityThread.java]

public void reportStop(PendingTransactionActions pendingActions) {
    mH.post(pendingActions.getStopInfo());
}

可以看到,這裏從pendingActions中取出先前保存的StopInfo,切換到主線程執行。StopInfo繼承自Runnable,將觸發它的run方法:
[PendingTransactionActions.java]

public void run() {
    // Tell activity manager we have been stopped.
    try {
        if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + mActivity);
        // TODO(lifecycler): Use interface callback instead of AMS.
        // 調用AMS的activityStopped方法以通知AMS
        ActivityManager.getService().activityStopped(
                mActivity.token, mState, mPersistentState, mDescription);
    } catch (RemoteException ex) {
        // 省略異常處理部分 ···
    }

activityStoppedLocked

AMS的activityStopped方法中會根據token查找對應的ActivityRecord,再調用其activityStoppedLocked方法:
[ActivityRecord.java]

final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
        CharSequence description) {
    final ActivityStack stack = getStack();
    if (mState != STOPPING) {
        Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
        // 移除超時消息
        stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
        return;
    }
    
    // 省略
    // ···
    
    if (!stopped) {
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
        stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
        stopped = true;
        setState(STOPPED, "activityStoppedLocked");

        mWindowContainerController.notifyAppStopped();

        if (finishing) {
            clearOptionsLocked();
        } else {
            if (deferRelaunchUntilPaused) {
                stack.destroyActivityLocked(this, true /* removeFromApp */, "stop-config");
                mStackSupervisor.resumeFocusedStackTopActivityLocked();
            } else {
                mStackSupervisor.updatePreviousProcessLocked(this);
            }
        }
    }
}

到這裏完成了Activity的stop操作和通知AMS。

總結

時序圖

啓動Activity的大致的流程如圖所示,AMS負責調度各Activity的生命週期,Activity執行完某一階段後,也需要通知到AMS,以便AMS進行下一步調度。
這個時序圖也印證了開頭前言中 Activity A 啓動 Activity B 的生命週期順序的結論確實是這樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章