Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities

The startup process needs to be combined with the Application. Juejin. Cn/post / 701209…

/ / check to see if the top visible activities are waiting for the if (normalMode) {try {the if (mStackSupervisor. AttachApplicationLocked (app)) {didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; }}Copy the code

Enter ActivityStackSupervisor

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException { final String processName = app.processName; boolean didSomething = false; 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; } // Add all activities from activityStack (Activity stack) to mTmpActivityList stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList); / / returns the current application of the top of the activity final ActivityRecord top = stack. TopRunningActivityLocked (); final int size = mTmpActivityList.size(); For (int I = 0; i < size; i++) { final ActivityRecord activity = mTmpActivityList.get(i); f (activity.app == null && app.uid == activity.info.applicationInfo.uid && processName.equals(activity.processName)) { try { if (realStartActivityLocked(activity, app, top == activity /* andResume */, true /* checkConfig */)) { didSomething = true; } } catch (RemoteException e) { throw e; } } } } } if (! didSomething) { ensureActivitiesVisibleLocked(null, 0, ! PRESERVE_WINDOWS); } return didSomething; }Copy the code

Enter the realStartActivityLocked method

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { ... ClientTransaction = ClientTransaction. Obtain (app.thread, r.aptoken); / / add the callback clientTransaction. AddCallback (LaunchActivityItem. Obtain (new Intent (r.i ntent), System. IdentityHashCode (r), r.info, mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, mService.isNextTransitionForward(), profilerInfo)); final ActivityLifecycleItem lifecycleItem; if (andResume) { lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } clientTransaction.setLifecycleStateRequest(lifecycleItem); / / to commit the transaction mService. GetLifecycleManager () scheduleTransaction (clientTransaction); . }Copy the code

Enter the ClientLifecycleManager


void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle();
    }
}
Copy the code

Enter the Schedule method of the ClientTransaction class

public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}
Copy the code

The mClient is actually the IApplicationThread

public static ClientTransaction obtain(IApplicationThread client, IBinder activityToken) {
    ClientTransaction instance = ObjectPool.obtain(ClientTransaction.class);
    if (instance == null) {
        instance = new ClientTransaction();
    }
    instance.mClient = client;
    instance.mActivityToken = activityToken;

    return instance;
}
Copy the code

Return to the scheduleTransaction method in ActivityThread

public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}
Copy the code

Enter the ActivityThread parent class ClientTransactionHandler

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
Copy the code

Go back to the handlerMessage in activityThread

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;
Copy the code

Enter the TransactionExecutor class and execute the execute method

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

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}
Copy the code

Go to the executeCallbacks method

public void executeCallbacks(ClientTransaction transaction) { final List<ClientTransactionItem> callbacks = transaction.getCallbacks(); if (callbacks == null) { // No callbacks to execute, return early. return; } log("Resolving callbacks"); 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(); for (int i = 0; i < size; ++ I) {// Get LaunchActivityItem final ClientTransactionItem item = callbacks.get(I); log("Resolving callback: " + item); final int postExecutionState = item.getPostExecutionState(); final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r, item.getPostExecutionState()); if (closestPreExecutionState ! = UNDEFINED) { cycleToPath(r, closestPreExecutionState); } // Perform the form creation request 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); }}}Copy the code

Go to the Execute method on the LaunchActivityItem

@Override public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) { Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); // Create an ActivityClientRecord object, ActivityClientRecord r = new ActivityClientRecord(Token, mIntent, mIdent, mInfo, mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState, mPendingResults, mPendingNewIntents, mIsForward, mProfilerInfo, client); / / callback to activityThread client. HandleLaunchActivity (r, pendingActions, null customIntent / * * /); Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER); }Copy the code

Go back to the handleLaunchActivity method in the activityThread class

public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) { ... Final Activity A = performLaunchActivity(r, customIntent); . }Copy the code

Enter the performLaunchActivity method

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { ... Try {/ / by reflecting Java objects created activity. Lang. This cl = appContext. GetClassLoader (); 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); }}... }Copy the code

Enter the newActivity method in the Instrumentation class

public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException { String pkg = intent ! = null && intent.getComponent() ! = null ? intent.getComponent().getPackageName() : null; return getFactory(pkg).instantiateActivity(cl, className, intent); }Copy the code

Enter the AppComponentFactory class

public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
        @Nullable Intent intent)
        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    return (Activity) cl.loadClass(className).newInstance();
}
Copy the code

At this point, the activity is created. Continue back to the activityThread class

activity.mCalled = false; If (r.i sPersistable ()) {/ / call the activity lifecycle method through mInstrumentation mInstrumentation. CallActivityOnCreate (activity, r.s Tate, r.persistentState); } else { mInstrumentation.callActivityOnCreate(activity, r.state); }Copy the code

Enter the callActivityOnCreate method in the Instrumentation class

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}
Copy the code

Enter the performCreate method in the activity

final void performCreate(Bundle icicle, PersistableBundle persistentState) { mCanEnterPictureInPicture = true; restoreHasCurrentPermissionRequest(icicle); if (persistentState ! = null) { onCreate(icicle, persistentState); } else { onCreate(icicle); } writeEventLog(LOG_AM_ON_CREATE_CALLED, "performCreate"); mActivityTransitionState.readState(icicle); mVisibleFromClient = ! mWindow.getWindowStyle().getBoolean( com.android.internal.R.styleable.Window_windowNoDisplay, false); mFragments.dispatchActivityCreated(); mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions()); }Copy the code

The general startup flow chart is as follows: