Activity的啟動過程

語言: CN / TW / HK

theme: cyanosis


開啟掘金成長之旅!這是我參與「掘金日新計劃 · 12 月更文挑戰」的第32天,點選檢視活動詳情

啟動一個Activity有兩個方法startActivity和startActivityForResult,前者最終會呼叫startActivityForResult因此直接對後者進行分析

1.Activity啟動的發起

``` //Activity#startActivityForResult public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { if (mParent == null) { options = transferSpringboardActivityOptions(options); Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); if (ar != null) { mMainThread.sendActivityResult( mToken, mEmbeddedID, requestCode, ar.getResultCode(), ar.getResultData()); } if (requestCode >= 0) { // If this start is requesting a result, we can avoid making // the activity visible until the result is received. Setting // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the // activity hidden during this time, to avoid flickering. // This can only be done when a result is requested because // that guarantees we will get information back when the // activity is finished, no matter what happens to it. mStartedActivity = true; }

    cancelInputsAndStartExitTransition(options);
    // TODO Consider clearing/flushing other event sources and events for child windows.
} else {
    if (options != null) {
        mParent.startActivityFromChild(this, intent, requestCode, options);
    } else {
        // Note we want to go through this method for compatibility with
        // existing applications that may have overridden it.
        mParent.startActivityFromChild(this, intent, requestCode);
    }
}

} ```

mParent == null的判斷中有這麼一行程式碼mMainThread.getApplicationThread(),其中的getApplication就是ApplicationThread它是ActivityThread的內部類,整合IApplication.Stub,也是個Binder物件,ActivityThreadApplicationThread在Activity的啟動過程中發揮著重要的作用。

接著再看一下mInstrumentation.execStartActivity做了什麼

//Instrumentation#execStartActivity @UnsupportedAppUsage 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); } if (mActivityMonitors != null) { synchronized (mSync) { final int N = mActivityMonitors.size(); for (int i=0; i<N; i++) { final ActivityMonitor am = mActivityMonitors.get(i); ActivityResult result = null; if (am.ignoreMatchingSpecificIntents()) { result = am.onStartActivity(intent); } if (result != null) { am.mHits++; return result; } else if (am.match(who, null, intent)) { am.mHits++; if (am.isBlocking()) { return requestCode >= 0 ? am.getResult() : null; } break; } } } } try { intent.migrateExtraStreamToClipData(who); intent.prepareToLeaveProcess(who); int result = ActivityTaskManager.getService().startActivity(whoThread, who.getBasePackageName(), who.getAttributionTag(), 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; }

由上面的程式碼可知啟動Activity的真正實現是由ActivityTaskManager.getService().startActivity()完成的

``` //ActivityTaskManager#getService public static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get(); }

@UnsupportedAppUsage(trackingBug = 129726065) private static final Singleton IActivityTaskManagerSingleton = new Singleton() { @Override protected IActivityTaskManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); return IActivityTaskManager.Stub.asInterface(b); } }; ```

ActivityTaskManager的主要工作就是管理Activity它接替了ActivityManager的一些工作。

看到Binder就可以明白了這裡是獲取一個跨程序服務,獲取的是ActivityTaskManagerService(ATMS),它繼承自IActivityTaskManager.Stub,是個Binder物件並且通過單例提供服務。

ATMS就是管理Activity及其容器(任務、堆疊、顯示等)的系統服務,執行在系統服務程序(system_server)。

execStartActivity方法中還有一個方法呼叫checkStartActivityResult

``` //Instrumentation#checkStartActivityResult @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) public static void checkStartActivityResult(int res, Object intent) { if (!ActivityManager.isStartResultFatalError(res)) { return; }

switch (res) {
    case ActivityManager.START_INTENT_NOT_RESOLVED:
    case ActivityManager.START_CLASS_NOT_FOUND:
        if (intent instanceof Intent && ((Intent)intent).getComponent() != null)
            throw new ActivityNotFoundException(
            "Unable to find explicit activity class "
            + ((Intent)intent).getComponent().toShortString()
            + "; have you declared this activity in your AndroidManifest.xml?");
        throw new ActivityNotFoundException(
            "No Activity found to handle " + intent);
    case ActivityManager.START_PERMISSION_DENIED:
        throw new SecurityException("Not allowed to start activity "
                                    + intent);
    case ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT:
        throw new AndroidRuntimeException(
            "FORWARD_RESULT_FLAG used while also requesting a result");
    case ActivityManager.START_NOT_ACTIVITY:
        throw new IllegalArgumentException(
            "PendingIntent is not an activity");
    case ActivityManager.START_NOT_VOICE_COMPATIBLE:
        throw new SecurityException(
            "Starting under voice control not allowed for: " + intent);
    case ActivityManager.START_VOICE_NOT_ACTIVE_SESSION:
        throw new IllegalStateException(
            "Session calling startVoiceActivity does not match active session");
    case ActivityManager.START_VOICE_HIDDEN_SESSION:
        throw new IllegalStateException(
            "Cannot start voice activity on a hidden session");
    case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
        throw new IllegalStateException(
            "Session calling startAssistantActivity does not match active session");
    case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
        throw new IllegalStateException(
            "Cannot start assistant activity on a hidden session");
    case ActivityManager.START_CANCELED:
        throw new AndroidRuntimeException("Activity could not be started for "
                                          + intent);
    default:
        throw new AndroidRuntimeException("Unknown error code "
                                          + res + " when starting " + intent);
}

} ```

checkStartActivityResult的程式碼中可以知道它的作用就是檢查啟動Activity的結果,無法正確啟動時就丟擲一個異常。

2.Activity的管理-ATMS

到這裡Activity的啟動流程就通過跨程序轉移到了ATMS中,接著分析ATMS中的startActivity方法

``` //ActivityTaskManagerService#startActivity @Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); }

//ActivityTaskManagerService#startActivityAsUser @Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /validateIncomingUser/); }

//ActivityTaskManagerService#startActivityAsUser 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("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();

} ```

在ATMS中的startActivity方法中一層層的深入看到最終呼叫的是startActivityAsUser方法,這個方法中首先呼叫getActivityStartController.obtainStart獲取到ActivityStarter例項,然後呼叫一系列方法(setCaller()、setUserId())等,最後通過execute()方法啟動Activity

//ActivityStater#execute 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(); } }

在execute中分了兩種情況,但是無論哪種情況最終都會進入到startActivity中,這個startActivity中呼叫startActivityUnchecked

``` //ActivityStarter#startActivity private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity, boolean restrictedBgActivity) { int result = START_CANCELED; final ActivityStack startedActivityStack; try { mService.mWindowManager.deferSurfaceLayout(); result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags, doResume, options, inTask, outActivity, restrictedBgActivity); } finally { final ActivityStack currentStack = r.getActivityStack(); startedActivityStack = currentStack != null ? currentStack : mTargetStack;

    if (ActivityManager.isStartResultSuccessful(result)) {
        if (startedActivityStack != null) {
            // If there is no state change (e.g. a resumed activity is reparented to
            // top of another display) to trigger a visibility/configuration checking,
            // we have to update the configuration for changing to different display.
            final ActivityRecord currentTop =
                startedActivityStack.topRunningActivityLocked();
            if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
                mRootActivityContainer.ensureVisibilityAndConfig(
                    currentTop, currentTop.getDisplayId(),
                    true /* markFrozenIfConfigChanged */, false /* deferResume */);
            }
        }
    } else {
        // If we are not able to proceed, disassociate the activity from the task.
        // Leaving an activity in an incomplete state can lead to issues, such as
        // performing operations without a window container.
        final ActivityStack stack = mStartActivity.getActivityStack();
        if (stack != null) {
            stack.finishActivityLocked(mStartActivity, RESULT_CANCELED,
                                       null /* intentResultData */, "startActivity", true /* oomAdj */);
        }

        // Stack should also be detached from display and be removed if it's empty.
        if (startedActivityStack != null && startedActivityStack.isAttached()
            && startedActivityStack.numActivities() == 0
            && !startedActivityStack.isActivityTypeHome()) {
            startedActivityStack.remove();
        }
    }
    mService.mWindowManager.continueSurfaceLayout();
}

postStartActivityProcessing(r, result, startedActivityStack);

return result;

} ```

然後在startActivityUnChecked方法中呼叫mRootActivityContainer.resumeFocusedStacksTopActivities

,RootActivityContainer是Android10新增的類,分擔了之前ActivityStackSupervisor的部分功能。

然後在resumeFocusedStacksTopActivites中進入了ActivityStack的resumeTopActivityUncheckedLocked方法中

``` //ActivityStack#resumeTopActivityUncheckedLocked //確保堆疊中最頂層的活動被恢復 @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;

} ```

在reumeToActivityUncheckedLocked方法中又進入了resumeTopActivityInnerLocked方法

``` //ActivityStack#resumeTopActivityInnerLocked private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { ... boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false); if (mResumedActivity != null) { if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Pausing " + mResumedActivity); // 暫停上一個Activity pausing |= startPausingLocked(userLeaving, false, next, false); } ... //這裡next.attachedToProcess(),只有啟動了的Activity才會返回true if (next.attachedToProcess()) { ...

            try {
                final ClientTransaction transaction =
                    ClientTransaction.obtain(next.app.getThread(), next.appToken);
                ...
                    //啟動了的Activity就傳送ResumeActivityItem事務給客戶端了,後面會講到
                    transaction.setLifecycleStateRequest(
                    ResumeActivityItem.obtain(next.app.getReportedProcState(),
                                              getDisplay().mDisplayContent.isNextTransitionForward()));
                mService.getLifecycleManager().scheduleTransaction(transaction);
                ....
                } catch (Exception e) {
                ....
                    mStackSupervisor.startSpecificActivityLocked(next, true, false);
                return true;
            }
        ....
        } else {
        ....
            if (SHOW_APP_STARTING_PREVIEW) {
                //這裡就是 冷啟動時 出現白屏 的原因了:取根activity的主題背景 展示StartingWindow
                next.showStartingWindow(null , false ,false);
            }
        // 繼續當前Activity,普通activity的正常啟動 關注這裡即可
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }
return true;

} ```

這裡先暫停上一個Actiivty然後在執行建立Activity的工作,最終進入了ActivityStackSupervisor.startSpecificActivityLocked方法。這裡有個點注意下,啟動activity前呼叫了next.showStartingWindow方法來展示一個window,這就是 冷啟動時 出現白屏 的原因了。

``` //ActivityStackSupervisor#startSpecificActivityLocked void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's application already running? final WindowProcessController wpc = mService.getProcessController(r.processName, r.info.applicationInfo.uid);

boolean knownToBeDead = false;
if (wpc != null && wpc.hasThread()) {
    try {
        realStartActivityLocked(r, wpc, andResume, checkConfig);
        return;
    } catch (RemoteException e) {
        Slog.w(TAG, "Exception when starting activity "
               + r.intent.getComponent().flattenToShortString(), e);
    }
    knownToBeDead = true;
}

...

    try {
        if (Trace.isTagEnabled(TRACE_TAG_ACTIVITY_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "dispatchingStartProcess:"
                             + r.processName);
        }
        // 上面的wpc != null && wpc.hasThread()不滿足的話,說明沒有程序,就會取建立程序
        final Message msg = PooledLambda.obtainMessage(
            ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
            r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
        mService.mH.sendMessage(msg);
    } finally {
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

} ```

這裡的判斷條件if (wpc != null && wpc.hasThread())的意思是是否啟動了應用程式,內部是通過IApplicationThread是否為空來判斷的,這裡只看應用已經被啟動的情況,這裡進入了realStartActivityLocked方法

``` //ActivityStackSupversion#realStartActivityLocked boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc, boolean andResume, boolean checkConfig) throws RemoteException {

...

    // Create activity launch transaction.
    final ClientTransaction clientTransaction = ClientTransaction.obtain(
    proc.getThread(), r.appToken);

final DisplayContent dc = r.getDisplay().mDisplayContent;
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, proc.getReportedProcState(),
                                                        r.icicle, r.persistentState, results, newIntents,
                                                        dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                                                        r.assistToken));

// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
    lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
} else {
    lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);

// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

...

    return true;

} ```

這個方法中獲取了ClientTransaction,它是一個容器,包含了等待客戶端處理的事務,客戶端接收後取出並執行。

然後使用clientTransaction.addCallback添加了LaunchActivityItem例項

//都是用來發送到客戶端的 private List<ClientTransactionItem> mActivityCallbacks; public void addCallback(ClientTransactionItem activityCallback) { if (mActivityCallbacks == null) { mActivityCallbacks = new ArrayList<>(); } mActivityCallbacks.add(activityCallback); }

LauncherActivityItem又是什麼

``` public static LaunchActivityItem obtain(Intent intent, int ident, ActivityInfo info, Configuration curConfig, Configuration overrideConfig, CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState, List pendingResults, List pendingNewIntents, boolean isForward, ProfilerInfo profilerInfo, IBinder assistToken) { LaunchActivityItem instance = ObjectPool.obtain(LaunchActivityItem.class); if (instance == null) { instance = new LaunchActivityItem(); } setValues(instance, intent, ident, info, curConfig, overrideConfig, compatInfo, referrer, voiceInteractor, procState, state, persistentState, pendingResults, pendingNewIntents, isForward, profilerInfo, assistToken);

return instance;

} ```

將LauncherActivityItem的例項新增到setValues中配置了各種引數。從名字可以知道它就是用來啟動Activity的,它又是怎麼發揮作用的呢?再回頭去看realStartActivityLocked,呼叫了

mService.getLifecycleManager().scheduleTransaction(clientTransaction);裡面的service就是ATMS,getLifecycleManager獲取的是ClientLifecycleManager例項,scheduleTransaction方法如下:

``` void scheduleTransaction(ClientTransaction transaction) throws RemoteException { final IApplicationThread client = transaction.getClient(); transaction.schedule(); if (!(client instanceof Binder)) { transaction.recycle(); } }

public void schedule() throws RemoteException { mClient.scheduleTransaction(this); } ```

呼叫的就是IApplicationThread的scheduleTransaction方法,因為IApplicationThread是ApplicationThread在系統程序中的代理所以真正執行的地方就是ApplicationThread,也就是說Activity的啟動操作又跨程序還給了客戶端。

總結一下,啟動Activity的操作從客戶端跨程序轉移到了ATMS中,然後ATMS通過ActivityStrater、ActivityStack、ActivityStackSupervisor對Activity任務、Activity棧,Activity管理後又用跨程序方式把正在啟動的過程轉移表到了客戶端。

3.切換執行緒及訊息處理

經過上面的分析進入了Application的scheduleTransaction,然後在Application的scheduleTransaction中可以看到又進入了ActivityThread的scheduleTransaction,ActvityThread的scheduleTransaction是在其父類CientTransactionHandler中

``` //ActivityThread#ApplicationThread#scheduleTransaction @Override public void scheduleTransaction(ClientTransaction transaction) throws RemoteException { ActivityThread.this.scheduleTransaction(transaction); }

//ClientTransactionHandler void scheduleTransaction(ClientTransaction transaction) { transaction.preExecute(this); sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction); } ```

sendMessage最終呼叫如下

private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) { if (DEBUG_MESSAGES) Slog.v( TAG, "SCHEDULE " + mH.codeToString(what) + " arg1=" + arg1 + " arg2=" + arg2 + "seq= " + seq); Message msg = Message.obtain(); msg.what = what; SomeArgs args = SomeArgs.obtain(); args.arg1 = obj; args.argi1 = arg1; args.argi2 = arg2; args.argi3 = seq; msg.obj = args; mH.sendMessage(msg); }

上面程式碼中sendMessage最終收益通過mH傳送了一個訊息,這個mH繼承自Handler,是Handler的一個子類,它利用sendMessage將訊息傳送到了主執行緒

class H extends Handler { ... }

那麼mH又是從哪個執行緒傳送的呢?

這就要從ApplicationThread的sceduleTransaction方法中看起,因為sendMessage是通過它呼叫的,已知ApplicationThread是通過跨程序呼叫的因此可以得出結論ApplicationThread的scheduleTransaction的呼叫是在Binder執行緒池中。

到這裡,訊息就在主執行緒處理了,那麼又是怎麼處理Activity啟動的呢?回到ActivityThread的方法scheduleTransaction的實現中,也就是它的父類ClientTransactionHandler,在sendMessage方法中傳遞了一個what引數ActivityThread.H.EXECUTE_TRANSACTION,這塊就是啟動Activiy處理的地方,看一下它的實現

class H extends Handler { public void handleMessage(Message msg) { case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); if (isSystem()) { // Client transactions inside system process are recycled on the client side // instead of ClientLifecycleManager to avoid being cleared before this // message is handled. transaction.recycle(); } // TODO(lifecycler): Recycle locally scheduled transactions. break; } }

從原始碼得知他進入了TransactionExecutor的execute方法,然後在executeCallbacks方法中遍歷所有callback,然後呼叫了ClientTransactionItem的execute方法

``` //TransactionExecutor#execute public void execute(ClientTransaction transaction) { if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

final IBinder token = transaction.getActivityToken();
 ...

executeCallbacks(transaction);

executeLifecycleState(transaction);
...

}

@VisibleForTesting public void executeCallbacks(ClientTransaction transaction) { final List callbacks = transaction.getCallbacks(); if (callbacks == null || callbacks.isEmpty()) { // No callbacks to execute, return early. return; } if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callbacks in transaction");

final IBinder token = transaction.getActivityToken();
ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

// In case when post-execution state of the last callback matches the final state requested
// for the activity in this transaction, we won't do the last transition here and do it when
// moving to final state instead (because it may contain additional parameters from server).
final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
    : UNDEFINED;
// Index of the last callback that requests some post-execution state.
final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

final int size = callbacks.size();
//遍歷所有callback
for (int i = 0; i < size; ++i) {
    final ClientTransactionItem item = callbacks.get(i);
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
    final int postExecutionState = item.getPostExecutionState();
    final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                                                                             item.getPostExecutionState());
    if (closestPreExecutionState != UNDEFINED) {
        cycleToPath(r, closestPreExecutionState, transaction);
    }

    item.execute(mTransactionHandler, token, mPendingActions);
    item.postExecute(mTransactionHandler, token, mPendingActions);
    if (r == null) {
        // Launch activity request will create an activity record.
        r = mTransactionHandler.getActivityClient(token);
    }

    if (postExecutionState != UNDEFINED && r != null) {
        // Skip the very last transition and perform it by explicit state request instead.
        final boolean shouldExcludeLastTransition =
            i == lastCallbackRequestingState && finalState == postExecutionState;
        cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
    }
}

} ```

ClientTransactionItem有個子類LauncherActivityItem,在它的裡面重寫了execute方法

@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client, mAssistToken); client.handleLaunchActivity(r, pendingActions, null /* customIntent */); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }

程式碼中的client.handleLaunchActivity的client就是ClientTransactionHandler,是在TransactionExecutor構造方法傳入的,而TransactionExecutor的構造是在ActivityThread中完成的

//ActivityThread private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

所以可以得出結論client的handleLaunchActivity就是ActivityThread的handleLauncherActivity方法。

總結:ApplicationThread把啟動Activity的操作通過mH切換到了主執行緒,走到了ActivityThread的hanldeLaunchActivity方法中。

4.Activity的啟動核心實現-初始化及生命週期

先看下ActivityThread中的handleLaunchActivity做了什麼

``` public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {

...
final Activity a = performLaunchActivity(r, customIntent);
...

} ```

``` private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { //獲取待啟動Activity的元件資訊 ActivityInfo aInfo = r.activityInfo; if (r.packageInfo == null) { r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, Context.CONTEXT_INCLUDE_CODE); }

ComponentName component = r.intent.getComponent();
if (component == null) {
    component = r.intent.resolveActivity(
        mInitialApplication.getPackageManager());
    r.intent.setComponent(component);
}

if (r.activityInfo.targetActivity != null) {
    component = new ComponentName(r.activityInfo.packageName,
                                  r.activityInfo.targetActivity);
}

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 {
    //獲取Application例項,如果有責直接返回如果沒有則建立
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

    if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
    if (localLOGV) Slog.v(
        TAG, r + ": app=" + app
        + ", appName=" + app.getPackageName()
        + ", pkg=" + r.packageInfo.getPackageName()
        + ", comp=" + r.intent.getComponent().toShortString()
        + ", dir=" + r.packageInfo.getAppDir());

    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;
        }
        appContext.setOuterContext(activity);
        //通過attach方法關聯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,
                        r.assistToken);

        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;
        //呼叫生命週期onCreate
        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            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;
    }
    r.setState(ON_CREATE);

    // updatePendingActivityConfiguration() reads from mActivities to update
    // ActivityClientRecord which runs in a different thread. Protect modifications to
    // mActivities to avoid race.
    synchronized (mResourcesManager) {
        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;

} ```

performLaunchActivity主要做了一下事情:

    • 通過ActivityClientRecord獲取待啟動Activity 的元件資訊,例如主題,啟動模式等
    • 通過mInstrumentation.newActivity建立Activity例項
    • 通過LoadedApk的makeApplication建立Application,內部也是通過mInstrumentation使用類載入器,建立後就呼叫了Instrumentation.callApplicationOnCreate方法,也就是Application的onCreate方法
    • 建立ContextImpl並通過activity.attach方法對重要資料進行初始化,關聯了Context的具體實現ContextImpl,attach內部還完成了Window建立,這樣Window接收到外部事件就可以傳遞給Activity了
    • 呼叫Activty的onCreate方法,是通過mInstrumentation.callActivityOnCreate完成的。

Activity的其他生命週期是如何被呼叫的

    • LaunchActivityItem 遠端App端的onCreate生命週期事務
    • ResumeActivityItem 遠端App端的onResume生命週期事務
    • PauseActivityItem 遠端App端的onPause生命週期事務
    • StopActivityItem 遠端App端的onStop生命週期事務
    • DestroyActivityItem 遠端App端onDestroy生命週期事務

另外梳理過程中涉及的幾個類:

    • ClientTransaction:客戶端事務處理者
    • ClientLifecycleManager:客戶端生命週期管理者
    • TransactionExecutor:遠端通訊事務執行者

那麼我們再來看看ResumeActivityItem吧。

在ActivityStackSupervisor的realStartActivityLocked方法中呼叫了resumeActivityItem,再回到TransactionExecutor的execute方法中還有一個方法executeLifecyclestate,這個方法中祛除了ActivityLifecycleItem並呼叫了execute方法,這裡實際上呼叫的就是ResumeActivityItem方法,最終走到ActivityThread的hanleResumeActivity方法,在handleResumeActivity方法中內部會走onStart、onResume。

handleResumeActivity主要做了以下事情:

    • 呼叫生命週期:通過performResumeActivity方法,內部呼叫生命週期onStart、onResume方法
    • 設定檢視可見:通過activity.makeVisible方法,新增window、設定可見。(所以檢視的真正可見是在onResume方法之後)