Activity.startactivity () is usually used to jump to a page, so how does it start the Activity?

There are a lot of information about this aspect on the Internet, follow the footsteps of predecessors, while reviewing the opportunity to explore.

The source code involved in this article is based on Android 10 (Android Q).

If you’re wrong, please point it out in the comments section.

An overview of the

Avoid coming up on the source paste face, see a face meng forced situation, here or first on a rough flow chart, comb clear to see the source code is much easier.

Based on Android 10, according to personal understanding of the drawing of slag. The details vary from version to version, but the overall flow is basically the same.

  • Let’s start with a few basic concepts:
  • ActivityThread:

The actual entry to the App process. In the main() method, the Looper message loop of the main thread Handler is opened to process system messages.

  • ApplicationThread:

The IApplicationThread agent class that communicates with the Binder processes. It is mainly used to call Binder agent of SYSTEM_server process to App process to manage the life cycle.

  • Instrumentation:

A unique lifecycle management concrete execution class for each App process. Activity and Application lifecycle management are implemented by this class through callXXX() series of methods.

  • ActivityTaskManagerService:

Used to manage activities and their containers (tasks, stacks, displays…) System services. Binder proxy calls that receive a request from the App process to start the Activity.

  • ActivityManagerService:

A system service that manages the state of activities and other components in a system process. Binder proxy calls that accept App processes to bind Application.

  • ActivityStarter:

Manage the controller that starts the Activity in the system process

  • ActivityStack:

The rollback stack where the Activity is located. Controls the order in which activities fall back, with the Activity currently in focus at the top of the stack.

  • ActivityStackSupervisor:

ActivityStack is the only management class in the system that has been pushed back.

  • ClientLifecycleManager:

Management classes that send specific life-cycle state transactions to App processes through Binder.

  • General process:
  1. StartActivity () notifies the System_Service process’s ActivityManagerService of the need to start the Activity through Binder communication

  2. The system_service process first migrates an Activity currently in the focus state to the onPause state. (Binder mode)

  3. Start the target Activity based on the Activity launch mode. (Skip 4 and 5 if the process already exists.)

  4. If the process where the new Activity is running does not exist in the system, the Zygote process is notified via Socket messages.

    Fork copies the Zygote process and calls the ActivityThread.main method reflectively.

  5. The ActivityThread.attach method notifies the System_Service process’s ActivityManagerService with Binder to bind and initialize the new process.

    ActivityManagerService then tells the new process to create the Application and execute the onCreate method.

  6. After the process is created and started, realStartActivityLocked is called to create and start the Activity, Binder notifies the process of the target Activity to execute a lifecycle transaction, and finally the activity.oncreate method is called to complete the startup transaction.

The source code parsing

From here on involves the source code call, limited space, only retain important core code.

1. Notify the system that the process needs to be redirected

Start the Activity by Activity. Eventually startActivityForResult () to start.

Here’s Android10 as an example, going back up:

//===========1. android.app.Activity==================
public void startActivity(Intent intent, @Nullable Bundle options) {
    if(options ! =null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1); }}public void startActivityForResult(...).{...// Call the activity with Instrumentation instances inside, start the activityInstrumentation.ActivityResult ar = mInstrumentation.execStartActivity(...) ; . }//=============2. android.app.Instrumentation==================
public ActivityResult execStartActivity(...).{...intresult = ActivityTaskManager.getService().startActivity(...) ; . }//===========3. android.app.ActivityTaskManager===================
public static IActivityTaskManager getService(a) {
    return IActivityTaskManagerSingleton.get();
}

private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
    new Singleton<IActivityTaskManager>() {
    @Override
    protected IActivityTaskManager create(a) {
        // Obtain the Binder agent class of the Service (ActivityTaskManager).
        final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
        returnIActivityTaskManager.Stub.asInterface(b); }};Copy the code

IActivityTaskManager. Stub Binder agent ActivityTaskManagerService implementation class. ExecStartActivity method through Binder mechanisms across processes call system_server process ActivityTaskManagerService. StartActivity () method.

About Binder Communications

Android IPC mechanism: Binder and Aidl

/ / = = = = = = = = = = = = = = = = = = = = system_server process = = = = = = = = = = = = = = = = = = = = = = = =

//4. com.android.server.wm.ActivityTaskManagerService
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    ActivityStartController getActivityStartController(a) {
        return mActivityStartController;
    }
    
    public final int startActivity(...).{
        returnstartActivityAsUser(...) }...public int startActivityAsUser(...).{
        Activitystarter.execute () is actually called
        returngetActivityStartController().obtainStarter(...) . .execute() } }//5. com.android.server.wm.ActivityStartController
ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}

Copy the code

ActivityStarter. Execute actually manages the start of the Activity.

In ActivityStarter, the ActivityStack that is currently in focus is pushed back to the top of the stack and is onPause before the target Activity is started.

ActivityStack is what is commonly known as a fallback stack.

TaskRecord is the task stack.

About task stack and rollback stack :(the treatment of task stack and return stack also varies greatly between versions)

The well-worn Activity task returns the stack

Android Review Notes – Task stack and return stack

/ / = = = = = = = = = = = = = = = = = = = = system_server process = = = = = = = = = = = = = = = = = = = = = = = =

//6. com.android.server.wm.ActivityStarter
class ActivityStarter {
    private final ActivityTaskManagerService mService;
    private final RootActivityContainer mRootActivityContainer;
    private final ActivityStackSupervisor mSupervisor;
    int execute(a) {...return startActivity(...)    
    }
 
    private int startActivity(...).{...// Create new Activity information in the task stack
        ActivityRecord r = newActivityRecord(...) . startActivityUnchecked(...) . }private int startActivityUnchecked(...).{... mRootActivityContainer.resumeFocusedStacksTopActivities(); . }}//7. com.android.server.wm.RootActivityContainer
class RootActivityContainer extends ConfigurationContainer.{
    boolean resumeFocusedStacksTopActivities(...).{
        // Get the current fallback stack that got the focus
        final ActivityStack focusedStack = display.getFocusedStack();
        if(focusedStack ! =null) { focusedStack.resumeTopActivityUncheckedLocked(...) ; }}}//8. com.android.server.wm.ActivityStack
class ActivityStack extends ConfigurationContainer {
    final ActivityTaskManagerService mService;
    
    boolean resumeTopActivityUncheckedLocked(...). { resumeTopActivityInnerLocked(...) ; }private boolean resumeTopActivityInnerLocked(...). {
        if(mResumedActivity ! =null) {
           	// Move the activity currently in focus to onPause state
            pausing |= startPausingLocked(...);
        }
        ...
        // Start a new Activity and proceed to onResumemStackSupervisor.startSpecificActivityLocked(...) ; }final boolean startPausingLocked(...).{
        // Notify the client lifecycle management class ClientLifecycleManager to place the activty currently in focus in OnPause state
        //PauseActivityItem is a subclass of ActivityLifecycleItem that represents the lifecycle state to be migratedmService.getLifecycleManager().scheduleTransaction(... ,PauseActivityItem.obtain(...) ); }}//9. com.android.server.wm.ActivityTaskManagerService
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    private final ClientLifecycleManager mLifecycleManager;
    ClientLifecycleManager getLifecycleManager(a) {
        returnmLifecycleManager; }}Copy the code

2. OnPause of the current focus Activity

In ActivityStack may end ActivityTaskManagerService using ClientLifecycleManager Binder agent call.

/ / = = = = = = = = = = = = = = = = = = = = system_server process = = = = = = = = = = = = = = = = = = = = = = = =

//10. com.android.server.wm.ClientLifecycleManager
// Communicate with the App process and manage the App process Activity lifecycle
class ClientLifecycleManager {
    void scheduleTransaction(@NonNull IApplicationThread client,...).{
        finalClientTransaction clientTransaction = transactionWithState(...) ; scheduleTransaction(clientTransaction); }void scheduleTransaction(ClientTransaction transaction).{
        // Switch to in-app methods using the proxy class ApplicationThread by communicating with Binder
        finalIApplicationThread client = transaction.getClient(); transaction.schedule(); }}//11. android.app.servertransaction.ClientTransaction
public class ClientTransaction implements Parcelable.ObjectPoolItem {
    privateIApplicationThread mClient; .public void schedule(a) throws RemoteException {
        mClient.scheduleTransaction(this); }}Copy the code

IApplicationThread agent implementation class ApplicationThread to switch back to the App process calls ActivityThread. ScheduleTransaction.

/ / = = = = = = = = = = = = = = = = = = = = = = = = = = = = = App process = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =

//12. android.app.ActivityThread.ApplicationThread
/ / android. App. ActivityThread, is the only subclass ClientTransactionHandler implementation
public final class ActivityThread extends ClientTransactionHandler {
    // Handler for the main thread
    final H mH = new H();
    // A system process transaction class dedicated to processing EXECUTE_TRANSACTION messages within the main thread Handler
    private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);
    
    // The scheduleTransaction method is in the parent class ClientTransactionHandler. The subclass is not overridden
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        // Send a message to the main thread Handler
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
    
    private void sendMessage(...). {... Message msg = Message.obtain(); . mH.sendMessage(msg); }// ApplicationThread is a private inner class for ActivityThreads. It is the IApplicationThread proxy class for Binder communication and is used by system processes to call App process methods
    private class ApplicationThread extends IApplicationThread.Stub { 
		@Override
        public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
            ActivityThread.this.scheduleTransaction(transaction); }}// The main thread handler class
    class H extends Handler {
        // Process messages from system services
        public void handleMessage(Message msg) {
            switch (msg.what) {
            	...
                case EXECUTE_TRANSACTION:
                        final ClientTransaction transaction = (ClientTransaction) msg.obj;
                        mTransactionExecutor.execute(transaction);
                       break; . }}}}Copy the code

In fact, the Binder communication calls are in the main thread in the process of the App sends a message Handler EXECUTE_TRANSACTION,. To the android App. Servertransaction. TransactionExecutor affairs to handle the system life cycle, State of the request to send before onPause android. The app. Servertransaction. PauseActivityItem class the execute () method.

//13.android.app.servertransaction.TransactionExecutor
public class TransactionExecutor {
    public void execute(ClientTransaction transaction) {... executeCallbacks(transaction); executeLifecycleState(transaction); }private void executeLifecycleState(ClientTransaction transaction) {
        // Get the current lifecycle transaction request
        finalActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); .// Execute the final transition with proper parameters.lifecycleItem.execute(mTransactionHandler, token, mPendingActions); . }}//14. android.app.servertransaction.PauseActivityItem
public class PauseActivityItem extends ActivityLifecycleItem {
	@Override
    public void execute(ClientTransactionHandler client, IBinder token,...) {...// Call handlePauseActivity in the App processclient.handlePauseActivity(token, ...) ; . }}Copy the code

The handlePauseActivity() method of ActivityThread, which is the ClientTransactionHandler implementation class, is then called

In each App process, there is only one ActivityThread as the main entry of the Application process **, which holds an instance of Instrumentation, used to track the life cycle of activities and applications within the management process.

//15. ===========android.app.ActivityThread==================

public final class ActivityThread extends ClientTransactionHandler {
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
    // Used specifically to manage the Application and Activity lifecycle within the process
    Instrumentation mInstrumentation;
    
    @Override
    public void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if(r ! =null) {... performPauseActivity(r, finished, reason, pendingActions); . }}private Bundle performPauseActivity(ActivityClientRecord r,...) {...final booleanshouldSaveState = ! r.activity.mFinished && r.isPreHoneycomb();if (shouldSaveState) {
            // Call the Activity onSaveInstanceState()callActivityOnSaveInstanceState(r); } performPauseActivityIfNeeded(r, reason); . }private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
        // Move the Activity lifecycle from Instrumentation to the onPause() statemInstrumentation.callActivityOnPause(r.activity); }}//16. android.app.Instrumentation
public class Instrumentation {
    public void callActivityOnPause(Activity activity) { activity.performPause(); }}//18. android.app.Activity
public class Activity extends ContextThemeWrapper.{
    final void performPause(a) {...// The subclass implements the onPause() lifecycleonPause(); . }}Copy the code

Finally, the Instrumentation class inside ActivityThread migrates the Activity lifecycle through the callActivityOnPause() series of methods.

3. Start a new Activity

After the currently focused Activity enters the onPause state, the new Activity starts the process of pushing.

This is why you should not do time-consuming operations on activity.onpause (). The entire process from onPause to the start of a new Activity is sequential, and the new Activity is not started until the onPause is finished.

The aforementioned ActivityStack. ResumeTopActivityInnerLocked () method, through ActivityStackSupervisor. StartSpecificActivityLocked (…). Method to start a new Activity.

//17. com.android.server.wm.ActivityStackSupervisor
public class ActivityStackSupervisor implements RecentTasks.Callbacks {
    void startSpecificActivityLocked(ActivityRecord r,...) {
        // Gets whether the process in which the new activity is running exists
        final WindowProcessController wpc = mService.getProcessController(r.processName, 		
        																r.info.applicationInfo.uid);
        if(wps ! =null){
            ...
            //1. The new Activity starts normally in an existing processrealStartActivityLocked(...) ; .return}.../ / 2. If there is no new activity process, first by ActivityManagerInternal. StartProcess () method creates a new process
        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

Process already exists

If the Activity is in a process that already exists (the same process), call realStartActivityLocked() directly to start the Activity.

// com.android.server.wm.ActivityStackSupervisor
public class ActivityStackSupervisor implements RecentTasks.Callbacks {
    boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,...) throws RemoteException {
        // Create the transaction that starts the Activity
        final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
        clientTransaction.addCallback(LaunchActivityItem.obtain(newIntent(r.intent),...) ; .// After starting the Activity, proceed to the onResume state in sequenceActivityLifecycleItem lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); . clientTransaction.setLifecycleStateRequest(lifecycleItem);// Execute a transactionmService.getLifecycleManager().scheduleTransaction(clientTransaction); }}Copy the code

Here comes the familiar getLifecycleManager().scheduleTransaction() method.

Switch according to the front of the current Activity to onPause state, execute transaction Activity life cycle approach, here will call App by Binder mechanisms in-process TransactionExecutor. The execute () method, And finally execute the execute() method that passes the past implementation of the ActivityLifecycleItem subclass. So, . Only need to pay attention to the android app. Servertransaction. LaunchActivityItem class with android. The app. Servertransaction. ResumeActivityItem class the execute the implementation of the can.

// android.app.servertransaction.LaunchActivityItem
public class LaunchActivityItem extends ClientTransactionItem {
	
    @Override
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        ActivityClientRecord r = newActivityClientRecord(token, mIntent,...) ;// Execute the ActivityThread method
        client.handleLaunchActivity(r, pendingActions, null); }}// android.app.servertransaction.ResumeActivityItem
public class ResumeActivityItem extends ActivityLifecycleItem {
    @Override
    public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
        // Execute the ActivityThread method
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,"RESUME_ACTIVITY");
    }
    
    @Override
    public int getTargetState(a) {
        // The target lifecycle is onResume
        returnON_RESUME; }}// android.app.servertransaction.TransactionExecutor
public class TransactionExecutor {
    public void execute(ClientTransaction transaction) {...// Add a callback transaction to the traversal execution transaction and execute
        executeCallbacks(transaction);
        // Execute the lifecycle migration requestexecuteLifecycleState(transaction); . }public void executeCallbacks(ClientTransaction transaction) {
        // Get a list of callbacks in the Activity transaction
        finalList<ClientTransactionItem> callbacks = transaction.getCallbacks(); .for (int i = 0; i < callbacks.size(); ++i) {
            finalClientTransactionItem item = callbacks.get(i); .// Execute the transaction in the callback (in this case, create the Activity and onCreate())item.execute(mTransactionHandler, token, mPendingActions); item.postExecute(mTransactionHandler, token, mPendingActions); . }}private void executeLifecycleState(ClientTransaction transaction) {
        finalActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest(); .// Complete the missing state from the current Activity lifecycle to the target lifecycle
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);    
	    // Perform transactions migrated to the target lifecycle
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }
    
    private void cycleToPath(ActivityClientRecord r, ... , ClientTransaction transaction) {...// Get the missing life cycle int array (all life cycles are represented by an int value)
        final IntArray path = mHelper.getLifecyclePath(start, finish, excludeLastState);    
        performLifecycleSequence(r, path, transaction);    
    }
    
    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) {
                ...
                // The target state of the ResumeActivityItem is onResume, so an onStart is missing.
                // Call onStart() internally
                case ON_START:
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break; . }}}Copy the code

Its internal call ActivityThread respectively. HandleLaunchActivity and ActivityThread. HandleResumeActivity () method.

And when the ResumeActivityItem transaction is executed, the cycleToPath() method is called to fill in the missing lifecycle (onStart()).

OnStart on the completion of the life cycle of the call for personal speculation, if not, please inform you.

//android.app.ActivityThread
public final class ActivityThread extends ClientTransactionHandler {
    
	public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {...// Create an instance of the Activity and execute the initialization and onCreate() methods
        finalActivity a = performLaunchActivity(r, customIntent); .return a;
    }
    
    @Override
    public void handleStartActivity(ActivityClientRecord r, PendingTransactionActions pendingActions) {
        final Activity activity = r.activity;
        activity.performStart("handleStartActivity");
        // Set the Activity lifecycle state to onStart
        r.setState(ON_START);
    }
    
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, ...) {...finalActivityClientRecord r = performResumeActivity(...) ; . }private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {... Activity activity =null; .// Create an instance of the Activity from Instrumentationactivity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); .// Initializes the Activity internal objectactivity.attach(...) ; .// Enable Instrumentation to control the Activity lifecyclemInstrumentation.callActivityOnCreate(...) ; .return activity;
    }
    
    
    public ActivityClientRecord performResumeActivity(IBinder token,...) {
        finalActivityClientRecord r = mActivities.get(token); .// Execute the Activity's onResume() method
        r.activity.performResume(r.startsNotResumed, reason);
        returnr; }}Copy the code

The end of the handleXXX() family of methods is left to Instrumentation to actually migrate the Activity to the specified lifecycle using the callActivityOnXXX() family of methods.

// android.app.Instrumentation
public class Instrumentation {
    
    public Activity newActivity(ClassLoader cl, String className, Intent intent).{ String pkg = intent ! =null&& intent.getComponent() ! =null
                ? intent.getComponent().getPackageName() : null;
        // Create an instance of the Activity through ClassLoader reflection
        return getFactory(pkg).instantiateActivity(cl, className, intent);
    }
      
    public void callActivityOnCreate(Activity activity, Bundle icicle) {... activity.performCreate(icicle); . }public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }
    
    public void callActivityOnResume(Activity activity) {... activity.onResume(); . }}// android.app.Activity
public class Activity.{
    private Instrumentation mInstrumentation;
    
    final void performCreate(Bundle icicle,...) {
        onCreate(icicle);
    }
    
    final void performStart(String reason) {
        mInstrumentation.callActivityOnStart(this);
    }
    
    final void performResume(boolean followedByPause, String reason) {
        performRestart(true /* start */, reason); . mInstrumentation.callActivityOnResume(this); . }// The onCreate() method in the subclass must be called super.oncreate ().
    protected void onCreate(@Nullable Bundle savedInstanceState) {... }// Subclass onStart() method, must call super.onstart ()
    protected void onStart(a) {... }// The onResume() method in the subclass must be called super.onreusume ()
    protected void onResume(a) {... }}Copy the code

Process does not exist

If the new Activity to other processes, and the target process does not exist, will through the inner class ActivityManagerService, first LocalService. StartProcessLocked () to create new processes.

// android.app.ActivityManagerInternal
public abstract class ActivityManagerInternal {
    
	public abstract void startProcess(String processName,...);
}

/ / com. Android. Server. Am. ActivityManagerService. LocalService, is the only subclass ActivityManagerInternal
// An inner class that belongs to ActivityManagerService
public class ActivityManagerService extends IActivityManager.Stub{
    /** * Manage all processes in the system */
    final ProcessList mProcessList = new ProcessList();
    
    public final class LocalService extends ActivityManagerInternal {
        @Override
        public void startProcess(String processName,...) {...synchronized (ActivityManagerService.this) {
                startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */.new HostingRecord(hostingType, hostingName),
                                   false /* allowWhileBooting */.false /* isolated */.true /* keepIfLarge */); }... }final ProcessRecord startProcessLocked(String processName,...) {
            // Create a new process with ProcessList
            returnmProcessList.startProcessLocked(processName,...) ; }}}// com.android.server.am.ProcessList
public final class ProcessList {
    ActivityManagerService mService;
    
    boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord,...) {...// Start the process. It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        / / android. App. ActivityThread class name, is one of the new process is the main entrance
        final String entryPoint = "android.app.ActivityThread";	
        returnstartProcessLocked(hostingRecord,entryPoint,...) ; }boolean startProcessLocked(HostingRecord hostingRecord,String entryPoint,ProcessRecord app, ..) {...finalProcess.ProcessStartResult startResult = startProcess(app.hostingRecord,entryPoint, ...) ; . }private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint,...){...final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app);
		// Send a message to the Zygote process through socket connection, and fork the new processstartResult = appZygote.getProcess().start(entryPoint, app.processName,...) . }}Copy the code

Is ultimately a system_service process through the socket communication, notify the fork new Zygote process, and in the process of Zygote, through this reflection calls. Android app. ActivityThread class’s main () method.

This paper mainly studies the application layer. For more in-depth part, please refer to the analysis of specific fork process in Zygote process fork process

How does Zygote fork an APP process

After the Zygote process is created, the system starts the SystemService process in the main() method and polls the socket for receiving the child process.

PS: Zygote is the parent process of all App and Laucher processes. All other processes are copied from Zygote process fork.

  • The SystemService process uses sockets to communicate with the Zygote process.

    Fork is not allowed in multithreaded environments, and Binder communication is a multithreaded operation (Binder proxy objects are called in the Binder thread and need to be switched back to the main thread by Handler).

    A parent Binder thread has a lock, and the child’s main thread is waiting for resources from its child thread, but the child thread is not copied from the parent, resulting in a deadlock.

//android.app.ActivityThread
public final class ActivityThread extends ClientTransactionHandler {
    public static void main(String[] args) {... ActivityThread thread =new ActivityThread();
        thread.attach(false, startSeq); . }private void attach(boolean system, long startSeq) {
        if(! system) {// Belongs to the newly created APP process.Obtain the Binder agent class of ActivityManagerService and invoke attachApplication()
            finalIActivityManager mgr = ActivityManager.getService(); mgr.attachApplication(mAppThread, startSeq); . }else{
            // Belongs to the system process. }}}Copy the code

The proxy implementation class for IActivityManager is ActivityManagerService, which is switched to the System_service process through Binder

/ / = = = = = = = = = = = = = = = = = = = = = = call system_service method in the process of the = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
// com.android.server.am.ActivityManagerService
public class ActivityManagerService extends IActivityManager.Stub{
    public ActivityTaskManagerInternal mAtmInternal;
    
    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) { attachApplicationLocked(thread, callingPid, callingUid, startSeq); . }}private final boolean attachApplicationLocked(IApplicationThread thread,int pid,...) {...//1. Communicate with Binder to call methods in App process and bind Application of App processthread.bindApplication(processName, appInfo, providers,...) ; .//2. If the Activity starts normally, create the initial ActivitydidSomething = mAtmInternal.attachApplication(app.getWindowProcessController()); }}Copy the code

There are two steps: start the Application and start the initial Activity.

  1. Start the Application

Using the Binder mechanism, called IApplicationThread agent implementation class ActivityThread. ApplicationThread method, Finally, the application.attach () and application.oncreate () methods are called in turn

//=============== App process =======================
// android.app.ActivityThread.ApplicationThread
private class ApplicationThread extends IApplicationThread.Stub {
    public final void bindApplication(String processName, ApplicationInfo appInfo,...){... AppBindData data =newAppBindData(); .// Send a BIND_APPLICATION message to the main thread HandlersendMessage(H.BIND_APPLICATION, data); }}// android.app.ActivityThread.H
class H extends Handler {
    public void handleMessage(Message msg) {...switch (msg.what) {
            caseBIND_APPLICATION: ... AppBindData data = (AppBindData)msg.obj; handleBindApplication(data); .break; . }}}//android.app.ActivityThread
public final class ActivityThread extends ClientTransactionHandler {
    
    private void handleBindApplication(AppBindData data) {... mInstrumentation =newInstrumentation(); . Application app; .// Create the Application configured in androidmanifest.xml
        app = data.info.makeApplication(data.restrictedBackupMode, null); .// Initialize the ContentProvider configured in androidmanifest.xmlinstallContentProviders(app, data.providers); .// Execute Application's onCreate() methodmInstrumentation.callApplicationOnCreate(app); }}// android.app.LoadedApk
public final class LoadedApk {
    public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {... Application app = mActivityThread.mInstrumentation.newApplication(...) ; .return app    
    }
}


// android.app.Instrumentation
public class Instrumentation {
    // Initialize Application
    static public Application newApplication(Class
        clazz, Context context)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }
    
    
    public void callApplicationOnCreate(Application app) { app.onCreate(); }}Copy the code
  1. Start the initial Activity

After Application of the initialization, is called ActivityTaskManagerInternal. AttachApplication () to start the initial Activity within the Application

/ / com. Android. Server. Wm. ActivityTaskManagerService. LocalService is the only subclass ActivityTaskManagerInternal implementation.
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    RootActivityContainer mRootActivityContainer;
    final class LocalService extends ActivityTaskManagerInternal {
        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
            synchronized(...). {returnmRootActivityContainer.attachApplication(wpc); }}}}// com.android.server.wm.RootActivityContainer
class RootActivityContainer extends ConfigurationContainer.{
    boolean attachApplication(WindowProcessController app) throws RemoteException {...// Familiar call, in fact, this is the same as starting a new Activity in the same processmStackSupervisor.realStartActivityLocked(activity, app,...) . }}Copy the code

Here again the familiar mStackSupervisor. RealStartActivityLocked () method, follow-up and start the Activity under the same with the process.

Afterword.

There are a lot of online introduction to the start process, but the best way is to follow the article to see the source code, in order to better comb out the whole process and details.

PS:

This article is actually written before, and then in the research of View drawing, when trying to update the Android 11 (Android R) was a wave of backstab, a rough look (is not to understand the source. JPG), feel quite a lot of changes.

There will be time to come back later to understand the new changes in detail and try to update the details of the differences with Android 11.

References:

Init Process Zygote process Starts the SystemServer process

Android10.0 application process creation process and Zygote fork process

Android 10 startActivity source code analysis

Zygote process started by the system