❤ ⅸ Android startActivity source code analysis (including starting new applications) ❤ ️

catalogue

Start a picture

Classes involved

1,Activity.java

1.1 startActivity()

1.2 startActivityForResult()

2,Instrumentation.java

2.1 execStartActivity()

3,ActivityTaskManage.java

3.1 getService()

3.2 IActivityTaskManagerSingleton

4,ActivityTaskManagerService.java

4.1 startActivity()

4.2 startActivityAsUser()

4.3 startActivityAsUser() has more parameters than the above

4.4 getActivityStartController()

5,ActivityStartController.java

5.1 obtainStarter();

6,ActivityStarter.java

6.1 execute()

6.2 executeRequest()

6.3 startActivityUnchecked()

6.4 startActivityInner()

7,RootWindowContainer.java

7.1 resumeFocusedTasksTopActivities()

8,Task.java

8.1 resumeTopActivityUncheckedLocked()

8.2 resumeTopActivityInnerLocked()

9,ActivityTaskSupervisor.class

9.1 startSpecificActivity()

9.2 process started

9.2.1 realStartActivityLocked()

9.2.2 ClientLifecycleManager.scheduleTransaction()

9.2.3 ClientTransaction.schedule()

9.2.4 ApplicationThread.scheduleTransaction()

9.2.5 ClientTransactionHandler.scheduleTransaction()

9.2.6 ActivityThread.H.handleMessage()

9.2.7 TransactionExecutor.execute()

9.2.8 TransactionExecutor.executeCallbacks()

9.2.9 TransactionExecutor.cycleToPath()

9.2.10 TransactionExecutor.performLifecycleSequence()

9.2.11 ClientTransactionHandler.handleLaunchActivity()

9.2.12 ActivityThread.handleLaunchActivity()

9.2.13 ActivityThread.performLaunchActivity()

9.2.14 Instrumentation.newActivity()

9.2.15 Instrumentation.callActivityOnCreate()

9.3 process not started

9.3.1 ATMS.startProcessAsync()

9.3.2 ActivityManagerInternal.startProcess()

9.3.3 ActivityManagerService.LocalService.startProcess()

9.3.4 ActivityManagerService.startProcessLocked()

9.3.5 ProcessList.startProcessLocked()

9.3.6 ProcessList.startProcess()

9.3.7 Process.start()

9.3.8 ZygoteProcess.start()

9.3.9 ZygoteProcess.startViaZygote()

9.3.10 ZygoteProcess.openZygoteSocketIfNeeded(abi)

9.4.11 ZygoteProcess.zygoteSendArgsAndGetResult()

9.4.12 ZygoteProcess.attemptZygoteSendArgsAndGetResult()

9.4.13 ZygoteInit.main()

9.4.14 ZygoteService.runSelectLoop()

9.4.15 ZygoteConnection.processOneCommand()

9.4.15 ActivityThread.main()

Start a picture

Source code version: Android 11(SDK 30)

Classes involved

  • Instrumentation: responsible for the establishment and life cycle control of applications and activities.

  • ActivityTaskManager: this class provides information about and interacts with an Activity and its containers, such as tasks, stacks, and displays.

  • Activity taskmanagerservice: a system service used to manage activities and their containers (tasks, displays, etc.). Before this job was AMS, it is now separated from AMS.

  • ActivityStartController: controller used to delegate Activity startup.

  • ActivityStarter: specifically responsible for the startup operation of an Activity. Its main functions include parsing Intent, creating ActivityRecord, and creating TaskRecordflex if possible

  • Activity stack: the stack management of activities in ATMS, which is used to record the sequence relationship and status information of started activities. Determine whether a new process needs to be started through the ActivityStack.

  • RootWindowContainer: the Root WindowContainer of the device.

  • TaskRecord: a concept of "Task" abstracted from ATMS, which is a stack for recording activityrecords. A "Task" contains several activityrecords. ATMS uses TaskRecord to ensure the sequence of Activity startup and exit.

  • Activity stack Supervisor: responsible for the management of all activity stacks. Three activity stacks, mHomeStack, mFocusedStack and mLastFocusedStack, are managed internally. Among them, mHomeStack manages the activity stack related to the Launcher; mFocusedStack manages the activity stack currently displayed in the foreground; mLastFocusedStack manages the activity stack last displayed in the foreground activity.

  • Activity Supervisor: manages the activity task stack.

  • ActivityThread: the ActivityThread runs in the UI thread (main thread), the real entrance of the App.

  • Application thread: used to realize the interaction between ATMS and ActivityThread.

  • ApplicationThreadProxy: the proxy of ApplicationThread on the server. ATMS communicates with ActivityThread through this agent.

  • Client lifecycle manager: the ability to combine multiple client lifecycle transaction requests and / or callbacks and execute them as a single transaction.

  • TransactionExecutor: classes that manage transaction execution in the correct order.

1,Activity.java

1.1 startActivity()

@Override
public void startActivity(Intent intent) {
    //Then look inside
    this.startActivity(intent, null);
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    ...
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

         Finally, the startActivityForResult method is called, and the - 1 passed in indicates that the result of startActivity does not need to be obtained.

1.2 startActivityForResult()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
    @Nullable Bundle options) {
    //mParent represents the parent class of the current activity,
    if (mParent == null) {
        options = transferSpringboardActivityOptions(options);
        //ActivityThread mMainThread;
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
        ...
    } else {
        ...
    }
}

         startActivityForResult calls the Instrumentation.execStartActivity method. The rest is left to the Instrumentation class.

         mMainThread is of ActivityThread type. ActivityThread can be understood as a process, which is the process where the Activity is located.

         Obtain a reference of ApplicationThread through mMainThread, which is used to realize inter process communication. Specifically, the system process where AMS is located notifies the application process of a series of operations.

         There are descriptions of Instrumentation, ActivityThread, ApplicationThread and other classes above.

2,Instrumentation.java

        frameworks/base/core/java/android/app/Instrumentation.java

/**
 * Base class for implementing application instrumentation code.
 */
public class Instrumentation {
    ...
}

2.1 execStartActivity()

 public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            //Check the results of starting the Activity
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

         In Instrumentation, ActivityTaskManager.getService().startActivity() is called. Let's take a closer look.

3,ActivityTaskManage.java

        frameworks/base/core/java/android/app/ActivityTaskManager.java

@TestApi
@SystemService(Context.ACTIVITY_TASK_SERVICE)
public class ActivityTaskManager {
    ...
}

3.1 getService()

    /** @hide */
    public static IActivityTaskManager getService() {
        return IActivityTaskManagerSingleton.get();
    }

3.2 IActivityTaskManagerSingleton

    @UnsupportedAppUsage(trackingBug = 129726065)
    private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
            new Singleton<IActivityTaskManager>() {
                @Override
                protected IActivityTaskManager create() {
                    //Proxy object (dynamic proxy)
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                    return IActivityTaskManager.Stub.asInterface(b);
                }
            };
            

         This actually returns a ActivityTaskManagerService, which presents a cross process (from the app process > system_service process) and then calls its startActivity method.

         In fact, this is to call the startActivity method of ATMS through AIDL and return the result of iaactivitytaskmanager.startActivity: the Activity has been started normally and successfully.

         So far, the focus of startActivity has successfully shifted from application process (app) to ATMS of system_service.

4,ActivityTaskManagerService.java

        frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    ...
}

4.1 startActivity()

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

4.2 startActivityAsUser()

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

4.3 startActivityAsUser() has more parameters than the above

//Here's the point
private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    assertPackageMatchesCallingUid(callingPackage);
    enforceNotIsolatedCaller("startActivityAsUser");

    userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
            Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");

    //  Switch to the user app stack here.
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();

    }

4.4 getActivityStartController()

    ActivityStartController getActivityStartController() {
        return mActivityStartController;
    }

5,ActivityStartController.java

/**
 * Controller for delegating activity launches.
 */
public class ActivityStartController {
    ...
}

5.1 obtainStarter();

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

6,ActivityStarter.java

        frameworks/base/services/core/java/com/android/server/wm/ActivityStarter.java

/**
 * Controller for interpreting how and then launching an activity.
 *
 * This class collects all the logic for determining how an intent and flags should be turned into
 * an activity and associated task and stack.
 */
class ActivityStarter {
    ...
}

6.1 execute()

    /**
     * Parse the necessary information according to the request parameters provided earlier and execute the request to start the activity.
     * @return The starter result.
     */
    int execute() {
        ...
                res = executeRequest(mRequest);
        ...
    }

6.2 executeRequest()

    /**
     * Activity What preparations need to be made before starting?
     * The normal Activity startup process will be through   startActivityUnchecked   reach   startActivityInner. 
     */
    private int executeRequest(Request request) {
        ...
        //Record of Activity
        ActivityRecord sourceRecord = null;
        ActivityRecord resultRecord = null;
        ...
        //Activity   Stack management
        mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
                request.voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask,
                restrictedBgActivity, intentGrants);

        ...
        return mLastStartActivityResult;
    }

         As you can see from the above code, after several methods of invocation, the object of ActivityStarter type is finally obtained through obtainStarter method, and then its execute() method is called.

         In the execute() method, its internal executeRequest() method is called again.

         Let's move on to startActivityUnchecked();

6.3 startActivityUnchecked()

    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, Task inTask,
                boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        ....
        try {
            ...
            result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
                    startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
        } finally {
            ...
        }

        postStartActivityProcessing(r, result, startedActivityRootTask);

        return result;
    }

6.4 startActivityInner()

    int startActivityInner(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, Task inTask,
            boolean restrictedBgActivity, NeededUriGrants intentGrants) {
        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor, restrictedBgActivity);

        //Calculation start mode
        computeLaunchingTaskFlags();
        computeSourceRootTask();
        //Set startup mode
        mIntent.setFlags(mLaunchFlags);
        ...

        //  Here comes the key point
        mRootWindowContainer.resumeFocusedTasksTopActivities(
                        mTargetRootTask, mStartActivity, mOptions, mTransientLaunch);
        ...

        return START_SUCCESS;
    }

         This is mRootWindowContainer. This is RootWindowContainer.

7,RootWindowContainer.java

        frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java

/** Root {@link WindowContainer} for the device. */
class RootWindowContainer extends WindowContainer<DisplayContent>
        implements DisplayManager.DisplayListener {
        ...
        }

7.1 resumeFocusedTasksTopActivities()

    boolean resumeFocusedTasksTopActivities(
            Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions,
            boolean deferPause) {
        ...
        boolean result = false;
        if (targetRootTask != null && (targetRootTask.isTopRootTaskInDisplayArea()
                || getTopDisplayFocusedRootTask() == targetRootTask)) {
            result = targetRootTask.resumeTopActivityUncheckedLocked(target, targetOptions,
                    deferPause);
        }

        ...
        return result;
    }

Of course, the targetRootTask seen here is an instance of the Task object. Let's track this method.

8,Task.java

        frameworks/base/services/core/java/com/android/server/wm/Task.java

class Task extends WindowContainer<WindowContainer> {
      ...
}

8.1 resumeTopActivityUncheckedLocked()

    @GuardedBy("mService")
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
        someActivityResumed = resumeTopActivityInnerLocked(prev, options, deferPause);
        ...
        return someActivityResumed;
    }

8.2 resumeTopActivityInnerLocked()

    @GuardedBy("mService")
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options,
            boolean deferPause) {
        ...
            try {
                ....
            } catch (Exception e) {
                ....
                //a key
                mTaskSupervisor.startSpecificActivity(next, true, false);
                return true;
            }
        ....
        return true;
    }

mTaskSupervisor: is an instance of the ActivityTaskSupervisor object. Let's take a look at its startSpecificActivity() method.

9,ActivityTaskSupervisor.class

        frameworks/base/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java

public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
      ...
}

9.1 startSpecificActivity()

    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        //  this   Activity   of   Application (process)   Is it already running?
        final WindowProcessController wpc =
                mService.getProcessController(r.processName, r.info.applicationInfo.uid);

        boolean knownToBeDead = false;
        if (wpc != null && wpc.hasThread()) {
            try {
                //Process started
                //Note 1: start the activity
                realStartActivityLocked(r, wpc, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                
            }
        }

        r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

        final boolean isTop = andResume && r.isTopRunningActivity();
        //Note 2: the process was not started
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

Note 1: process started.

Note 2: the process was not started.

9.2 process started

9.2.1 realStartActivityLocked()

    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
            boolean andResume, boolean checkConfig) throws RemoteException {

        ...
                //establish   Activity   Activated   transaction
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.appToken);

                final boolean isTransitionForward = r.isTransitionForward();
                clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        mergedConfiguration.getGlobalConfiguration(),
                        mergedConfiguration.getOverrideConfiguration(), r.compat,
                        r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                        r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
                        r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken,
                        r.getLaunchedFromBubble()));

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

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
         
        ...
        return true;
    }

         This mService is an instance of ActivityTaskManagerService(ATMS). mService. Getlifecycle manager() returns a clientllifecycle manager object. If you want to see what scheduleTransaction() is, you can only find it.

9.2.2 ClientLifecycleManager.scheduleTransaction()

        frameworks/base/services/core/java/com/android/server/wm/ClientLifecycleManager.java

    //Here we introduce a startup   Activity   of   transaction
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        final IApplicationThread client = transaction.getClient();
        //Note 1
        transaction.schedule();
        if (!(client instanceof Binder)) {
            //  If   client   If it is not an instance of Binder, it is a remote call, and the object can be safely recycled.
            //  After a transaction is executed on the client in the ActivityThread, all objects used for local calls are reclaimed.
            transaction.recycle();
        }
    }

         From the method, we can see that transaction is a ClientTransaction. Let's go straight to him.

9.2.3 ClientTransaction.schedule()

    /** Target client. */
    private IApplicationThread mClient;
    
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

         When we see the iaapplicationthread, let's go straight to the ApplicationThread.

9.2.4 ApplicationThread.scheduleTransaction()

        frameworks/base/core/java/android/app/ActivityThread.java

         ApplicationThread belongs to the inner class of ActivityThread.

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    ...
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
        ...
    }
    ...
}

         There is no scheduleTransaction method in the ActivityThread class. In this case, you can directly find its parent class ClientTransactionHandler.

9.2.5 ClientTransactionHandler.scheduleTransaction()

        frameworks/base/core/java/android/app/ClientTransactionHandler.java

public abstract class ClientTransactionHandler {
    /** Prepare and schedule transaction for execution. */
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}

         From here, we can see that he sent an ActivityThread. H. execute by calling the sendMessage() method_ For the transaction message, let's go back to its subclass ActivityThread.

9.2.6 ActivityThread.H.handleMessage()

         H here is the inner class of ActivityThread.

    // An executor that performs multi-step transactions.
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    class H extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                        ...
                        case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) {
                        transaction.recycle();
                    }
                    break;
                    ...
            }
        }
    }

         mTransactionExecutor here is the executor of transactions.

9.2.7 TransactionExecutor.execute()

        frameworks/base/core/java/android/app/servertransaction/TransactionExecutor.java

    public void execute(ClientTransaction transaction) {
        ...
        executeCallbacks(transaction);
        ...
    }

9.2.8 TransactionExecutor.executeCallbacks()

    /** Cycle through all states requested by callbacks and execute them at proper times. */
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ...
        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);
        ...
        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) {
            ...
            if (postExecutionState != UNDEFINED && r != null) {
                //  a key
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

         The focus of this method is cycleToPath(), let's continue.

9.2.9 TransactionExecutor.cycleToPath()

    private void cycleToPath(ActivityClientRecord r, int finish, boolean excludeLastState,
            ClientTransaction transaction) {
        final int start = r.getLifecycleState();
        //IntArray: implements a growing array of int primitives.
        //Get the path to execute the life cycle this time
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);
        performLifecycleSequence(r, path, transaction);
    }

9.2.10 TransactionExecutor.performLifecycleSequence()

    /** Transition the client through previously initialized state sequence. */
    private void performLifecycleSequence(ActivityClientRecord r, IntArray path,
            ClientTransaction transaction) {
        final int size = path.size();
        for (int i = 0, state; i < size; i++) {
            state = path.get(i);
            
            switch (state) {
                case ON_CREATE:
                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                            null /* customIntent */);
                    break;
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions,
                            null /* activityOptions */);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                            false /* userLeaving */, 0 /* configChanges */, mPendingActions,
                            "LIFECYCLER_PAUSE_ACTIVITY");
                    break;
                case ON_STOP:
                    mTransactionHandler.handleStopActivity(r, 0 /* configChanges */,
                            mPendingActions, false /* finalStateRequest */,
                            "LIFECYCLER_STOP_ACTIVITY");
                    break;
                case ON_DESTROY:
                    mTransactionHandler.handleDestroyActivity(r, false /* finishing */,
                            0 /* configChanges */, false /* getNonConfigInstance */,
                            "performLifecycleSequence. cycling to:" + path.get(size - 1));
                    break;
                case ON_RESTART:
                    mTransactionHandler.performRestartActivity(r, false /* start */);
                    break;
                default:
                    throw new IllegalArgumentException("Unexpected lifecycle state: " + state);
            }
        }
    }

Here we finally see the familiar content, the life cycle of Activity, so excited ha ha.

         Here we are on_ Take create as an example. As can be seen from the above code_ Create is actually an int value (constant), which we won't describe here. mTransactionHandler is an instance of ClientTransactionHandler. Look directly at the handleLaunchActivity() method.

9.2.11 ClientTransactionHandler.handleLaunchActivity()

        frameworks/base/core/java/android/app/ClientTransactionHandler.java

public abstract class ClientTransactionHandler {
    ...
    /** Perform activity launch. */
    public abstract Activity handleLaunchActivity(@NonNull ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent);
    ...    
}

         It can be seen from the above that handleLaunchActivity() is an abstract method. ActivityThread is its subclass. You can only find its subclass ActivityThread to see the specific implementation.

9.2.12 ActivityThread.handleLaunchActivity()

    /**
     * Extended implementation of activity launch. Used when server requests a launch or relaunch.
     */
    @Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
        //  Creating   activity   Previous initialization
        if (ThreadedRenderer.sRendererEnabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
            HardwareRenderer.preload();
        }
        //initialization   Activity   of   WindowManager, each   Activity   Will correspond to a "window".
        WindowManagerGlobal.initialize();

        //  Tips   GraphicsEnvironment   Activity   Starting in process.
        GraphicsEnvironment.hintActivityLaunch();

        //Focus here: Activity   Core implementation of startup.
        final Activity a = performLaunchActivity(r, customIntent);
        ...
        return a;
    }

         performLaunchActivity(), the core implementation of Activity startup. Let's look down

9.2.13 ActivityThread.performLaunchActivity()

    /**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //Note 1:   Newly instantiated   Activity   Object.
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            ...
        } catch (Exception e) {
            ...
        }
                //Important: call activity.attach().
                //establish   Activity   And   Context   The link between.
                //establish   PhoneWindow   Object, and with   Activity   Perform associated operations.
                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, r.shareableActivityToken);
                        
                //The persistableMode property is set to:   ActivityInfo.PERSIST_ACROSS_REBOOTS(persistAcrossReboots);
                //Note 2: Execution   Activity   of   onCreate()   method.
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
        return activity;
    }

         First of all, let's see that M instrumentation is actually instrumentation. It is also useful in the startactivity forresult section of this article. Instrumentation is responsible for the establishment and life cycle control of applications and activities.

         Here we use his two methods. Let's have a look.

9.2.14 Instrumentation.newActivity()

    /**
     * @param cl The classloader used to instantiate the object.
     * @param className realization   Activity   The name of the class of the object.
     * @param intent Specifies the name of the activity class to instantiate   Intent   Object.
     * 
     * @return Newly instantiated   Activity   Object.
     */
    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);
    }

         pkg is the package name of intent.

         getFactory(pkg) obtains AppComponentFactory through the obtained package name. Then call its instantiateActivity() method to get Activity.

9.2.14.1 Instrumentation.getFactory()

    private AppComponentFactory getFactory(String pkg) {
        if (pkg == null) {
            ...
            return AppComponentFactory.DEFAULT;
        }
        if (mThread == null) {
            ....
            return AppComponentFactory.DEFAULT;
        }
        LoadedApk apk = mThread.peekPackageInfo(pkg, true);
        // This is in the case of starting up "android".
        if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
        return apk.getAppFactory();
    }

9.2.14.2 AppComponentFactory.instantiateActivity()

        frameworks/base/core/java/android/app/AppComponentFactory.java

/**
  * For control   manifest   Element instantiated interface.
  *
  * @see #instantiateApplication
  * @see #instantiateActivity
  * @see #instantiateClassLoader
  * @see #instantiateService
  * @see #instantiateReceiver
  * @see #instantiateProvider
  */
public class AppComponentFactory {
      ...
}

instantiateActivity()

    /**
     * This method is only used to provide hooks for instantiation.
     * It does not provide for   Activity   Object.
     * The returned object will not be initialized to   Context   And should not be used with others   android   API   Interaction.
     */
    public @NonNull Activity instantiateActivity(@NonNull ClassLoader cl, @NonNull String className,
            @Nullable Intent intent)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Activity) cl.loadClass(className).newInstance();
    }

Here, get the instance of Activity through reflection.

9.2.15 Instrumentation.callActivityOnCreate()

    /**
     * implement   A call to the Activity#onCreate method.
     *
     * @param activity Creating   activity  . 
     * @param icicle Pass a previously frozen state (or null) to   onCreate()  . 
     */
    public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        //a key
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

         From here, you can see that you are about to enter the interior of the Activity.

9.2.15.1 Activity.performCreate()

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        ...
        //a key
        if (persistentState != null) {
            onCreate(icicle, persistentState);
        } else {
            onCreate(icicle);
        }
        ...
    }

         As you can see here, the process in the startSpecificActivity() method has started, which is the end. startActivity started successfully. In combination with 9.2.13 ActivityThread.performLaunchActivity(), we can see that the attach() method call in the Activity is earlier than the onCreate() method.

         Let's go back to 9.1 startSpecificActivity() to check the process that has not been started.

9.3 process not started

         Since the process is not started, it must be started first. Let's keep watching.

    final ActivityTaskManagerService mService;
    void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
        ....
        mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
    }

         From here, we can see that mService is actually ATMS. Let's go.

9.3.1 ATMS.startProcessAsync()

    void startProcessAsync(ActivityRecord activity, boolean knownToBeDead, boolean isTop,
            String hostingType) {
        try {
            ...
            //  Publish a message to start the process to avoid holding   ATMS   Called in case of lock   AMS   Deadlock may occur.
            final Message m = PooledLambda.obtainMessage(ActivityManagerInternal::startProcess,
                    mAmInternal, activity.processName, activity.info.applicationInfo, knownToBeDead,
                    isTop, hostingType, activity.intent.getComponent());
            mH.sendMessage(m);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }

9.3.2 ActivityManagerInternal.startProcess()

        frameworks/base/core/java/android/app/ActivityManagerInternal.java

/**
 * Activity manager local system service interface.
 */
public abstract class ActivityManagerInternal {
    /** Starts a given process. */
    public abstract void startProcess(String processName, ApplicationInfo info,
            boolean knownToBeDead, boolean isTop, String hostingType, ComponentName hostingName);
}

         This is an abstract class. Let's find its implementation class ActivityManagerService.LocalService.

9.3.3 ActivityManagerService.LocalService.startProcess()

        frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {   
    ...
    @VisibleForTesting
    public final class LocalService extends ActivityManagerInternal
            implements ActivityManagerLocal {
        ...
        @Override
        public void startProcess(String processName, ApplicationInfo info, boolean knownToBeDead,
                boolean isTop, String hostingType, ComponentName hostingName) {
            try {
                synchronized (ActivityManagerService.this) {
                    //  If the process is called top   App, please set a prompt so that when starting the process, the highest priority can be applied immediately to avoid attaching top   Before the app process, the cpu was preempted by other processes.
                    
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName, isTop),
                            ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE, false /* allowWhileBooting */,
                            false /* isolated */);
                }
            } finally {
            }
        }
    }
}    

9.3.4 ActivityManagerService.startProcessLocked()

    /**
     * Process management.
     */
    final ProcessList mProcessList;
    @GuardedBy("this")
    final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, int zygotePolicyFlags, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, zygotePolicyFlags, allowWhileBooting, isolated, 0 /* isolatedUid */,
                keepIfLarge, null /* ABI override */, null /* entryPoint */,
                null /* entryPointArgs */, null /* crashHandler */);
    }

         As you can see, the mProcessList here is ProcessList.

9.3.5 ProcessList.startProcessLocked()

        frameworks/base/services/core/java/com/android/server/am/ProcessList.java

    @GuardedBy("mService")
    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
            boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean allowWhileBooting, boolean isolated, int isolatedUid,
            boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs,
            Runnable crashHandler) {
        ...
        final boolean success =
                startProcessLocked(app, hostingRecord, zygotePolicyFlags, abiOverride);
        checkSlow(startTime, "startProcess: done starting proc!");
        return success ? app : null;
    }
    ------------Split line-------------
    @GuardedBy("mService")
    final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, String abiOverride) {
        return startProcessLocked(app, hostingRecord, zygotePolicyFlags,
                false /* disableHiddenApiChecks */, false /* disableTestApiChecks */,
                false /* mountExtStorageFull */, abiOverride);
    }
    ------------Split line-------------
    /**
     * @return {@code true} if process start is successful, false otherwise.
     */
    @GuardedBy("mService")
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,
            int zygotePolicyFlags, boolean disableHiddenApiChecks, boolean disableTestApiChecks,
            boolean mountExtStorageFull, String abiOverride) {
            ...
            return startProcessLocked(hostingRecord, entryPoint, app, uid, gids,
                    runtimeFlags, zygotePolicyFlags, mountExternal, seInfo, requiredAbi,
                    instructionSet, invokeWith, startTime);
    }
    ------------Split line-------------
    @GuardedBy("mService")
    boolean startProcessLocked(HostingRecord hostingRecord, String entryPoint, ProcessRecord app,
            int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
                ...
                //Finally get to the point.
                final Process.ProcessStartResult startResult = startProcess(hostingRecord,
                        entryPoint, app,
                        uid, gids, runtimeFlags, zygotePolicyFlags, mountExternal, seInfo,
                        requiredAbi, instructionSet, invokeWith, startTime);
                
                handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper,
                        startSeq, false);
                ...
    }

         After repeated calls, you finally see the key code startProcess().

9.3.6 ProcessList.startProcess()

    private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int zygotePolicyFlags,
            int mountExternal, String seInfo, String requiredAbi, String instructionSet,
            String invokeWith, long startTime) {

            ...
            final Process.ProcessStartResult startResult;
            if (hostingRecord.usesWebviewZygote()) {
                //Should the process start from   webview   zygote   produce
                startResult = startWebView(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName, app.mDisabledCompatChanges,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else if (hostingRecord.usesAppZygote()) {
                //Should the process be from the application   zygote   Generated in
                final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);

                //  We cannot isolate application data from stored data because the parent   zygote   This has already been done.
                startResult = appZygote.getProcess().start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, null, app.info.packageName,
                        /*zygotePolicyFlags=*/ ZYGOTE_POLICY_FLAG_EMPTY, isTopApp,
                        app.mDisabledCompatChanges, pkgDataInfoMap, whitelistedAppDataInfoMap,
                        false, false,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            } else {
                startResult = Process.start(entryPoint,
                        app.processName, uid, uid, gids, runtimeFlags, mountExternal,
                        app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                        app.info.dataDir, invokeWith, app.info.packageName, zygotePolicyFlags,
                        isTopApp, app.mDisabledCompatChanges, pkgDataInfoMap,
                        whitelistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs,
                        new String[]{PROC_START_SEQ_IDENT + app.startSeq});
            }
            ...
   }

         In either case, Process.start() will be called;

9.3.7 Process.start()

        frameworks/base/core/java/android/os/Process.java

    /**
     * State associated with the zygote process.
     */
    public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess();
    public static ProcessStartResult start(@NonNull final String processClass,
                                           @Nullable final String niceName,
                                           int uid, int gid, @Nullable int[] gids,
                                           int runtimeFlags,
                                           int mountExternal,
                                           int targetSdkVersion,
                                           @Nullable String seInfo,
                                           @NonNull String abi,
                                           @Nullable String instructionSet,
                                           @Nullable String appDataDir,
                                           @Nullable String invokeWith,
                                           @Nullable String packageName,
                                           int zygotePolicyFlags,
                                           boolean isTopApp,
                                           @Nullable long[] disabledCompatChanges,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   pkgDataInfoMap,
                                           @Nullable Map<String, Pair<String, Long>>
                                                   whitelistedDataInfoMap,
                                           boolean bindMountAppsData,
                                           boolean bindMountAppStorageDirs,
                                           @Nullable String[] zygoteArgs) {
        return ZYGOTE_PROCESS.start(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, packageName,
                    zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, whitelistedDataInfoMap, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
    }

         Zygote here_ Process is ZygoteProcess. Call its start() method.

9.3.8 ZygoteProcess.start()

        frameworks/base/core/java/android/os/ZygoteProcess.java

    /**
     * Start a new process.
     * If the process is enabled, a new process is created and processClass is executed there   Static main()   Function.
     * After the function returns, the process will continue to run.
     * 
     * If the process is not enabled, a new thread is created in the caller process and called there   processclass   of   main(). 
     * 
     * niceName Parameter, if not an empty string, is a custom name that is provided to the process instead of being used   processClass. 
     * This allows you to create processes that are easy to identify, even if you use the same basic   processClass   To start them.
     *
     * When   invokeWith   Not for   null   When, the process will be used as a new   app   instead of   zygote   fork   Start.
     * Please note that this applies only to   uid   0   Or when runtimeFlags   contain   DEBUG_ENABLE_DEBUGGER   Time.
     *
     * @param processClass Class used as the main entry point for the process.
     * @param niceName A more readable name for the process.
     * @param uid The user under which the process will run   ID. 
     * @param gid The group under which the process will run   ID. 
     * @param gids Additional groups associated with the process   ID. 
     * @param runtimeFlags Additional signs.
     * @param targetSdkVersion Application objectives   SDK   edition.
     * @param seInfo null-ok New process   SELinux   Information.
     * @param abi Not empty. This application should use   ABI. 
     * @param instructionsSet null-Determine the instruction set to use.
     * @param appDataDir null-ok The data directory for the application.
     * @param invokeWith null-ok The command to call.
     * @param packageName null-ok The package name to which this process belongs.
     * @param zygotePolicyFlags Flag that determines how to start the application.
     * @param isTopApp Whether the process is started for a high priority application.
     * @param disabledCompatChanges Disable compatibility changes for the process being started   null-ok   List.
     * @param pkgDataInfoMap Mapping from related package names to private data directory volumes   UUID   and   inode   Number.
     * @param allowlistedDataInfoList Mapping from allowed package names to private data directory volumes   UUID   and   inode   Number.
     * @param bindMountAppsData zygote Need to mount   CE   and   DE   data
     * @param bindMountAppStorageDirs zygote Do you need to mount Android/obb   And Android/data.
     *
     * @param zygoteArgs provide for   Zygote   Additional parameters for the process.
     * @return An object that describes the result of an attempt to start a process.
     * @throws RuntimeException A fatal startup failure occurred
     */
    //There are a lot of parameters passed from the previous method, so I won't describe them much
    public final Process.ProcessStartResult start(...) {
        ...
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    runtimeFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, invokeWith, /*startChildZygote=*/ false,
                    packageName, zygotePolicyFlags, isTopApp, disabledCompatChanges,
                    pkgDataInfoMap, allowlistedDataInfoList, bindMountAppsData,
                    bindMountAppStorageDirs, zygoteArgs);
        ...
    }

9.3.9 ZygoteProcess.startViaZygote()

    //There are a lot of parameters passed from the previous method, so I won't describe them much
    private Process.ProcessStartResult startViaZygote(...)
                                                      throws ZygoteStartFailedEx {
        ...
        synchronized(mLock) {
            // The USAP pool can not be used if the application will not use the systems graphics
            // driver.  If that driver is requested use the Zygote application start path.
            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),
                                              zygotePolicyFlags,
                                              argsForZygote);
        }
    }

         Before looking at zygoteSendArgsAndGetResult(), let's look at openzygotesocketifneed (ABI).

9.3.10 ZygoteProcess.openZygoteSocketIfNeeded()

    /**
     * Try opening a   session   Socket to have compatibility   ABI   of   Zygote   Process (if not already open).   If compatible   session   If the socket has been opened, the   session   socket. 
     *
     * This feature may block and you may have to try to connect to more than one   Zygotes   To find the right one   Zygotes.    Need to keep   mLock. 
     */
    @GuardedBy("mLock")
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        try {
            attemptConnectionToPrimaryZygote();

            ...
    }
    ------------Split line-------------
    /**
     * If Primary   If Zygote does not exist or is disconnected, create one for it   ZygoteState. 
     */
    @GuardedBy("mLock")
    private void attemptConnectionToPrimaryZygote() throws IOException {
        if (primaryZygoteState == null || primaryZygoteState.isClosed()) {
            primaryZygoteState =
                    ZygoteState.connect(mZygoteSocketAddress, mUsapPoolSocketAddress);
            ...
        }
    }
    ------------Split line-------------
    static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress,
            @Nullable LocalSocketAddress usapSocketAddress)
            throws IOException {
        ...
        //Create LocalSocket
        final LocalSocket zygoteSessionSocket = new LocalSocket();
            //Connect the zygoteSessionSocket to the endpoint.
            //Can only be called on instances that are not connected.
            zygoteSessionSocket.connect(zygoteSocketAddress);
        ...
    }

         After opening the ZygoteSocket, let's take a look at zygoteSendArgsAndGetResult();

9.4.11 ZygoteProcess.zygoteSendArgsAndGetResult()

    @GuardedBy("mLock")
    private Process.ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, int zygotePolicyFlags, @NonNull ArrayList<String> args)
            throws ZygoteStartFailedEx {
        ...
        String msgStr = args.size() + "\n" + String.join("\n", args) + "\n";        
        return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr);
    }

9.4.12 ZygoteProcess.attemptZygoteSendArgsAndGetResult()

    private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult(
            ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx {
        try {
            final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter;
            final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream;

            //Write, call zygote(ZygoteInit).
            zygoteWriter.write(msgStr);
            zygoteWriter.flush();

            // Always read the entire result from the input stream to avoid leaving
            // bytes in the stream for future process starts to accidentally stumble
            // upon.
            Process.ProcessStartResult result = new Process.ProcessStartResult();
            //Read and block
            result.pid = zygoteInputStream.readInt();
            result.usingWrapper = zygoteInputStream.readBoolean();

            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }

            return result;
        } catch (IOException ex) {
            zygoteState.close();
            Log.e(LOG_TAG, "IO Exception while communicating with Zygote - "
                    + ex.toString());
            throw new ZygoteStartFailedEx(ex);
        }
    }

9.4.13 ZygoteInit.main()

    @UnsupportedAppUsage
    public static void main(String[] argv) {
            ...
            //  zygote   Permanent cycle.
            caller = zygoteServer.runSelectLoop(abiList);
    }

9.4.14 ZygoteService.runSelectLoop()

    /**
     * function   zygote   Process selection loop.   Accept new connections when they occur and read them one at a time   spawn-request   Value command.
     * @param abiList this   zygote   Supportive   ABI   List.
     */
    Runnable runSelectLoop(String abiList) {
        ...
                            //Session socket accepted from the Zygote server socket
                            ZygoteConnection connection = peers.get(pollIndex);
                            //adopt   fork   start-up   Child process (application)
                            final Runnable command = connection.processOneCommand(this);
        ...                                   
    }

9.4.15 ZygoteConnection.processOneCommand()

        frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java

    Runnable processOneCommand(ZygoteServer zygoteServer) {
        ...
        pid = Zygote.forkAndSpecialize(parsedArgs.mUid, parsedArgs.mGid, parsedArgs.mGids,
                parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mIsTopApp,
                parsedArgs.mPkgDataInfoList, parsedArgs.mWhitelistedDataInfoList,
                parsedArgs.mBindMountAppDataDirs, parsedArgs.mBindMountAppStorageDirs);
        ...
    }

         fork out a new process (APP). The program entry of an app is ActivityThread.main().

9.4.15 ActivityThread.main()

        frameworks/base/core/java/android/app/ActivityThread.java

         When the ActivityThread is initialized, a message loop has been created, so it is not necessary to specify a loop when creating a Handler in the main thread. If you use a Handler in other threads, you need to create a message loop using loop. Prepare() and loop. Loop().

    public static void main(String[] args) {
        ...
        //Initializes the of the current process   Looper   object
        Looper.prepareMainLooper();
        ...
        ActivityThread thread = new ActivityThread();
        //Create Application here
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        //  call   Looper   of   loop   Method to open an infinite loop.
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

         Looper: take out the Message from the MessageQueue, and then process the task specified in the Message (startActivity).

         At this point, whether you call startActivity() to start the page or startActivity() to start the interface of other processes is completed.

         If you have any questions, please correct them.

Relevant recommendations

❤️ How does the Android app start? ❤️

❤️ Android Runtime (ART) and Dalvik ❤️

❤️ Packaging process of Android Apk ❤️ Only two pictures are needed

❤️ Android interprets the installation process of Apk from the source code ❤️

Keywords: Android

Added by jackohara on Sun, 10 Oct 2021 04:55:42 +0300