Today, I looked again at the Activity launch process, which is helpful to strengthen the internal work of the developer. However, as most of the internal implementation of Android is relatively complex, the study of internal implementation should focus more on the grasp of the overall process, rather than go into the details of the code, which often leads to the state of “missing the forest for the trees”.

This process is designed into THE Binder mechanism of IPC. If you are not familiar with Binder mechanism, don’t panic. This article will not affect your reading.

Starting with the Activity’s startActivity method, you end up calling the startActivityForResult method with the following pseudocode

public class Activity {
    public ActivityThread mMainThread;
    public Instrumentation mInstrumentation;
    public void startActivity(a) { startActivityForResult(); }}Copy the code

StartActivityForResult method is called Instrumentation. ExecStartActivity () method, this startup process is transferred to the Instrumentation class.

  • First transfer

Start the process to Instrumentation class, see execStartActivity () method, Instrumentation. ExecStartActivity ()

Method called

ActivityManagerNative.getDefault().startActivity()

This startup process is transferred to ActivityManagerNative. GetDefault () class.

  • Second transfer

ActivityManagerNative is an abstract class. Look at the getDefault() method to return an instance object.

public abstract class ActivityManagerNative {
    static public IActivityManager getDefault(a) {
        returnActivityManager.getService(); }}Copy the code

Then track

public class ActivityManager {
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create(a) {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    returnam; }};public static IActivityManager getService(a) {
        returnIActivityManagerSingleton.get(); }}Copy the code

The end result is the IActivityManager instance created by calling singleton.create (), which is the AMS proxy object on the client side. The call to ams.startActivity () is executed by the Binder thread. The client thread suspends and is handled by the Binder thread, but the process is asynchronous and not synchronous, so the ams.startActivity () method returns immediately without blocking the UI thread. ActivityManagerService class is a Binder class.

public class ActivityManagerService extends IActivityManager.Stub {}Copy the code
  • Third transfer

The Activity is started by AMS, which is performed in Binder threads. ActivityManagerService.startActivity()

Method call

ActivityStackSupervisor.startActivityMayWait()

This moves the startup process to the ActivityStackSupervisor class.

  • Fourth transfer

ActivityStackSupervisor.startActivityMayWait()

Method call

ActivityStackSuperVisor.startActivityLocked()

Call in release

ActivityStackSuperVisor.startActivityUnckeckedLocked()

Method is called

ActivirtStack.resumeTopActivitiesLocked()

This moves the startup process to the ActivirtStack class.

  • Fifth transfer

ActivirtStack.resumeTopActivitiesLocked()

Method call

ActivirtStack.resumeTopActivityInnerLocked()

Method call

ActivityStackSuperVisor.startSpecificActivityLocked()

The process is again handed over to the ActivityStackSupervisor class, so the startup process is again moved to the ActivityStackSupervisor class.

  • Sixth transfer

ActivityStackSuperVisor.startSpecificActivityLocked()

Method call

ActivityStackSuperVisor.realStartActivityLocked()

In this way, the Activity startup process is passed between ActivityStackSupervisor and ActivityStack.

ActivityStackSuperVisor.realStartActivityLocked()

Method call

ApplicationThread. ScheduleLaunchActivity (),

The app. Thread. ScheduleLaunchActivity (), app. The thread is IApplicationThread type, The implementor of IApplicationThread is the inner class ApplicationThread of ActivityThread.

private class ApplicationThread extends IApplicationThread.Stub {}Copy the code

The ApplicationThread class is a Binder class that again refers to the Binder mechanism of IPC, cutting calls back to the client Binder thread.

Rao the start-up process of a large circle Activity eventually returned to ApplicationThread class, ApplicationThread. ScheduleLaunchActivity ()

Method that sends a message to the ActivityThread Handler, handing the operation over to the UI thread.

  • Seventh transfer

The ActivityThread inner class H inherits the Handler and overrides the handleMessage() method. Handler.handleMessage()

Method call

ActivityThread.handleLaunchActivity()

This moves the startup process to the class that calls ActivityThread.

  • Eighth transfer

ActivityThread. HandleLaunchActivity () {ActivityThread. PerformLaunchActivity () / / method after the final Activity object creation and start the process ActivityThread. HandleResumeActivity () / / the Activity lifecycle function called onResume ()}

  • Ninth transfer

ActivityThread.performLaunchActivity()

Methods do more things.

1. Obtain information about the Activity component to be started from the ActivityClientRecord.

2. Through Instrumentation. NewActivity () method USES the class loader created the Activity object.

3. Call LoadedApk. MakeApplication () method, makeApplication () method is called Instrumentation. NewAppliction () to try to create the Application object. Why not? Because the Application has already been created, it won’t be created again.

4. Create the ContextImpl object and call the activity.Attach () method to initialize some important data.

5. Call the Activity lifecycle method onCreate()

After this, the Activity starts once.