Let’s start with a picture

Core classes

ActivityThread: the main thread of the application

Instrumentation is responsible for invoking activities and Application lifecycles.

ActivityTaskManagerService (ATMS) : responsible for managing the activity ActivityManagerService (AMS) : the previous version is responsible for the management of the activity, and generally the same parent class

ActivityTaskManagerInternal ActivityTaskManagerService provides an abstract class, the real implementation in ActivityTaskManagerService# LocalService

ActivityStarter: starts the startup mode and processes flags

ActivityStack: Is responsible for managing individual stacks of activities and their state, i.e. the execution of specific launches, etc

ActivityStackSupervisor: Similar to ActivityStack, but designs window-related operations

ClientTransactionItem: An abstract class that implements a concrete activity lifecycle. Subclasses: LaunchActivityItem, etc

ClientTransaction: Processes related information and life cycle states

TransactionExecutor performs ClientTransaction

ClientLifecycleManager Management calls for the lifecycle

1. Start the

  1. Activity

    • -> startActivity -> startActivityForResult() ->
  2. mInstrumentation.execStartActivity()

    Finally, ActivityTaskManager#getService is called to get IActivityTaskManager, which is an IPC call, The server is ActivityTaskManagerService IActivityTaskManager, So ActivityTaskManager. GetService (). StartActivity final call is ActivityTaskManagerService# startActivity

  3. Is ActivityStartController getActivityStartController get. You get ActivityStarter with ActivityStartController#obtainStarter. ActivityStarter#execute is eventually called

    ActivityStarter

    • StartActivityUnchecked () is called, which determines how to start an Activity based on the start flag and Activity startup mode

    RootActivityContainer

    -> mRootActivityContainer.resumeFocusedStacksTopActivities()

    ActivityStack

    -> focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);

    -> resumeTopActivityInnerLocked()

    • It determines if any activities are in a Resume state, and if so, it executes Pausing, which calls startPausingLocked. And then execute startSpecificActivityLocked methods start to start the Activity

    1. The Activity at the top of the stack exits using onPause

    -> startPausingLocked()

    In ActivityStack. StartPausingLocked () method by using the approach of ClientLifecycleManager scheduleTransaction PausingActivityItem event to join to the execution plan, Start the pausing process at the top of the stack

    mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                            prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                                    prev.configChangeFlags, pauseImmediately));
    Copy the code

    ClientLifecycleManager#scheduleTransaction

    Then in the internal call ClientTransaction. Schedule method, jump straight into the ApplicationThread scheduleTransaction method

    And in ClientTransactionHandler scheduleTransaction method calls the sendMessage method, this method is an abstract, Actually now ClientTransactionHandler ActivityThread derived classes, ActivityThread. The sendMessage method sends a message Handler of the internal name is H.

The last call is to the method in ActivityThread. Let’s take a look at ActivityThread#handlePauseActivity.

Then call the performResumeActivity() method,

So we end up calling Instrumentation#callActivityOnPause, so we see the familiar onPause()

The Activity of creating

Let’s go back to ActivityStack#startPausingLocked above after executing. Invokes the mStackSupervisor. StartSpecificActivityLocked (next, true, true)

If processes and threads exist, realStartActivityLocked is called directly. If not, mservice.mh.sendMessage (MSG) is called. MH is the inner class H of the ActivityThread we mentioned above.

ActivityStackSupervisor.startSpecificActivityLocked()

If processes and threads exist, realStartActivityLocked is called directly. If not, mservice.mh.sendMessage (MSG) is called. MH is the inner class H of the ActivityThread we mentioned above.

2. Create a process

\platform_frameworks_base-master\services\core\java\com\android\server\wm\ActivityStackSupervisor.java
final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);
Copy the code

Through ActivityManagerInternal: : startProcess

The implementation of ActivityManagerInternal class ActivityManagerService#LocalService

Will call ActivityManagerService. LocalService. StartProcessLocked method, after many jump will eventually through the Process. The start method to create Process for application.

After call step by step, can be found the ultimate call the Zygote and socket communication ways to fork out a new Zygote process, and according to the transfer of “android. The app. ActivityThread” string, The object is reflected and initialized with the Main method of ActivityThread.

The main thread of the application where the Activity is located initializes

  • ActivityThread.main
  • ActivityThread.attach

ActivityThread is initialized in the activityThread. main method, Looper object is created for the main thread, Looper is started by calling looper.loop (), and the object of custom Handler class H is used as the Handler for the main thread. Next jump to the ActivityThread.attach method

In the ActivityThread.attach method, you first bind an Application to the Application through ActivityManagerService, then add a garbage collector observer, Whenever the system triggers garbage collection, it calculates how much memory the application is using in the run method and attempts to free memory if it exceeds three-quarters of the total. Finally, add a Config callback to the root View to receive information about config changes.

final IActivityManager mgr = ActivityManager.getService();
    try {
         mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
          throw ex.rethrowFromSystemServer();
    }
Copy the code

Enter attachApplication for AMS, which is to notify system processes of reference startup. In this case, threads are started and attachApplicationLocked() is called.

thread.bindApplication(processName, appInfo, providers, instr2.mClass, profilerInfo, instr2.mArguments, instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || ! normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions, disabledCompatChanges); .// See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in "+ app, e); badApp = true; }}Copy the code
  • Configure the properties of the application
  • thread.bindApplcation
  • mAtmInternal.attachApplication(app.getWindowProcessController());

One thread bindApplicaion, namely ActivityThread. ApplicationThread. BindApplication

ActivityThread.bindApplication()

sendMessage(H.BIND_APPLICATION, data);
Copy the code

/ / in ActivityThread. H handleMessage

case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
Copy the code

Completes application initialization in handleBindApplication,

if (! data.restrictedBackupMode) { if (! ArrayUtils.isEmpty(data.providers)) { installContentProviders(app, data.providers); } } mInstrumentation.callApplicationOnCreate(app);Copy the code

You can see here that the ContentProvider precedes the application.oncreate method,

– Next, start the Activity

 didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
Copy the code

class LocalService extends ActivityTaskManagerInternal

  • Call ATMS. LocalService. AttachApplication
 public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized (mGlobalLockWithoutBoost) {
                returnmRootActivityContainer.attachApplication(wpc); }}Copy the code

The last call ActivityStack realStartActivityLocked

clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
mService.getLifecycleManager().scheduleTransaction(clientTransaction);
Copy the code

The subsequent process is similar to pasue and Resume

3. Call realStartActivityLocked() directly

In ActivityStackSupervisor. RealStartActivityLocked () method to add LaunchActivityItem ClientTransaction object callback, and then set the current state of the life cycle, The last call ClientLifeMananger. ScheduleTransaction method is carried out

And then, as before,

ApplicationThread is an inner class in an ActivityThread

ClientTransaction mClient schedule method is a IApplicationThread type, inner class ApplicationThread ActivityThread derived the interface class and implements the corresponding method. So jump directly to the scheduleTransaction method in ApplicationThread. The ActivityThread class does not define a scheduleTransaction method, so the scheduleTransaction method of its parent class ClientTransactionHandler is called.

    frameworks/base/core/java/android/app/ActivityThread.java
    private class ApplicationThread extends IApplicationThread.Stub {
        ...
        @Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction);
        }
    }

    frameworks/base/core/java/android/app/ClientTransactionHandler.java
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
Copy the code

In ClientTransactionHandler. ScheduleTransaction method calls the sendMessage method, this method is an abstract, Actually now ClientTransactionHandler ActivityThread derived classes, ActivityThread. The sendMessage method sends a message Handler of the internal name is H.

    frameworks/base/core/java/android/app/ActivityThread.java
    void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0.0, false);
    }

    private void sendMessage(int what, Object obj, int arg1) {
        sendMessage(what, obj, arg1, 0, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }

    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + "" + mH.codeToString(what)
            + ":" + arg1 + "/"+ obj); Message msg = Message.obtain(); msg.what = what; msg.obj = obj; msg.arg1 = arg1; msg.arg2 = arg2; if (async) { msg.setAsynchronous(true); } mH.sendMessage(msg); } public void handleMessage(Message msg) { ... case EXECUTE_TRANSACTION: final ClientTransaction transaction = (ClientTransaction) msg.obj; mTransactionExecutor.execute(transaction); . break; . }Copy the code

Handler H instance to receive EXECUTE_TRANSACTION news calls TransactionExecutor. The state of the execute method switching Activity. TransactionExecutor. Inside the execute method to implement Callbacks, then change the Activity of the current state of the life cycle. Then execute the ExecutelifeccleState method.

executeCallbacks(transaction);
executeLifecycleState(transaction);
Copy the code

Inside the executeLifecycleState method, will go to call TransactionExecutor. CycleToPath state before the execution of the current life cycle, and then execute ActivityLifecycleItem. The execute method. So executeLifecycleState method calls in the execute method is LaunchActivityItem. The execute method.

frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

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

then

    frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        ...
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    }
Copy the code

The ActivityThread#handleLaunchActivity method is entered

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null.null);

    // Initialize before Creating the activity // Initialize WindowManagerGlobal
    WindowManagerGlobal.initialize();

    //1. Start an Activity, which involves creating an Activity object and eventually returning an Activity objectActivity a = Activity a = performLaunchActivity(r, customIntent); if (a ! =null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
	//2. Enter the onResume methodhandleResumeActivity(r.token, false, r.isForward, ! r.activity.mFinished && ! r.startsNotResumed, r.lastProcessedSeq, reason); if (! r.activity.mFinished && r.startsNotResumed) {//3. If not displayed in foreground, enter onPuse method
            performPauseActivityIfNeeded(r, reason);

        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
	//4. AMS finishes the activity if it fails to start
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null, Activity.DONT_FINISH_TASK_WITH_ACTIVITY); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); }}}Copy the code

Jump step by step, through the above code execution to ActivityThread. PerformLaunchActivity method. In ActivityThread. PerformLaunchActivity method first on the Activity of the ComponentName, ContextImpl, Activity, and the Application object is initialized and interconnected, Then set the Activity theme, and finally call Instrumentation. CallActivityOnCreate method.

ActivityThread#perfomLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {

	//1 Creates an Activity object
	activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);

	//2 Calls the attach method of the 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);

	/ / 3. Callback onCreate
	mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);

}
Copy the code

Analysis of attach method

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

	// create PhoneWindowmWindow = new PhoneWindow(this, window); mWindow.setWindowControllerCallback(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); . mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) ! =0); if (mParent ! =null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
Copy the code

The attach method focuses on two main points: 1. The attachBaseContext method is called; 2. Create PhoneWindow and assign the value to mWindow

From the Instrumentation callActivityOnCreate method to follow, jump to the Activity. The performCreate method, here we see the Activity. The onCreate method.

\core\java\android\app\Activity.java
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        dispatchActivityPreCreated(icicle);
        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());
        dispatchActivityPostCreated(icicle);
    }
Copy the code

At this point, we have basically analyzed the Activity startup process

conclusion

Activity launch process, Android 9 and Android 10 have a lot of changes, I refer to a lot of articles, thanks to those blogs, let me analyze the source code with ideas. If there is something wrong or bad, you are welcome to criticize and correct.

  • Activity start process analysis

  • Reference: Analysis of the Activity startup process