Key points:

  • What lifecycle callbacks the Activity goes through when it starts
  • General process of cold start, what components are involved, and what is the communication process?
  • How does the lifecycle callback work during an Activity launch?

General flow chart:

1. Interaction between process A and AMS

Here’s a look at the source flow by starting the Activity across processes:

  1. A call startActivity, need and AMS interaction, the need to need to get to the proxy object of AMS Binder is above the AMP, through ActivityManagerNative. GetDefault (), Amps’ startActivity method is called, Binder is used to communicate with mremote. transact method, and AMS ‘onTransact method is used to obtain the requested Activity parameter information:

    mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0); . @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags){ switch(code){ case START_ACTIVITY_TRANSACTION:{ startActivity(app,callingPackage,intent,...) }}}Copy the code
  2. AMS startActivity method inside the main startSpecificActivityLocked function called, in this function to determine whether the target process already exists. If both conditions are met, the target will call realStartActivityLocked, which we’ll look at later. If the above conditions are not met, to invoke the mService. StartProcessLocked (r.p rocessName,…). Method to start the process.

2. AMS starts target process B

           

  1. StartProcessLocked method first calls the Process. The start (” android. App. ActivityThread “,) method to the Zygote sends a startup Process requests, and inform the Zygote Process started, Load the main function of the ActivityThread class, return the process PID when it is started, and send a delay message to AMS’s Handler, requiring the target process to report to AMS within 10 seconds of starting, otherwise AMS will clear the target process.

  2. The process. start method calls the startViaZygote(processClass,) function, which does two things: open the Socket to Zygote, and send the start Process parameters through the Socket.

  3. The main Zygote logic is to call Zygote. Forkandwte (…) in the runOnce function. Create the child process, and then do their own work in the parent and child processes

  4. The parent sends the PID of the child through the Socket to AMS via hanleParentProc (PID)

  5. The child process calls the handleChildProc function to do some general initialization, such as enabling Binder mechanisms; Execute the application’s entry function, the Main function of ActivityThread

  6. The main function for ActivityThread creates an ActivityThread object and calls Thread.attach (false) in order to report to AMS, as mentioned in the first section above.

  7. Inside the attach method, which is actually a cross-process call, passes first

    IActivityManager mgr = ActivityManagerNative.getDefault();
    Copy the code

    Get the Binder proxy object for AMS and call

    mgr.attachApplication(mAppThread);
    Copy the code

    MAppThread is a Binder object on the application side, ApplicationThread (ATP in the top image), so that the AMS side can call the application side.

  8. The attachApplication method uses the bindApplication to initiate the Application by using the ApplicationThread

    mStactSupervisor.attachApplicationLoacked(app);
    Copy the code

    Initialize the suspended Activity object.

  9. In attachapplicationloc, that’s going to call

    ActivityRecord hr = stack.topRunningActivityLocked(null);
    Copy the code

    It should be understood that there are two stacks in AMS, one is Launch desktop stack, and the other is non-desktop stack mFocusedStack. Stack here is mFocusedStack, and it will return the ActivityRecord at the top of the stack. Our target Activity was already at the top of the stack, but never initialized. And then call

    realStartActivityLocked(hr,app,true,true);
    Copy the code

    Method to start the Activity. If we were to start the same process instead of another process, this second block would not exist and instead would call realStartActivityLocked directly.

3. Several steps to start the Activity on the application side

  1. RealStartActivityLocked function will be called app. Thread. ScheduleLaunchActivity (new Intent (r.i ntent),…). ; Call scheduleLaunchActivity with the previously registered Binder OBJECT ATP.

    ActivityClientRecord r = new ActivityClientRecord(); . sendMessage(H.LAUNCH_ACTIVITY,r);Copy the code

    Encapsulate an ActivityClientRecord message and throw it into the main thread Handler (mH).

  2. It’s in the main thread

    Final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck(...) ; handleLaunchActivity(r,null);Copy the code

    The getPackageInfoNoCheck function is mainly used to generate a LoadedApk object, which is used to store our APK information. Since we need a ClassLoader to load the Activity class in APK, we have prepared this in advance.

  3. HandleLaunchActivity is divided into two parts, one is performLaunchActivity, one is handleResumeActivity.

  4. performLaunchActivity

    Activity activity = mInstrumentation.newActivity(...) ; / / before returning to create good Application app = r.p. AckageInfo makeApplication (false, mInstrumentation); / / generated ContextImpl Context appContext = createBaseContextForActivity (r, activity); Attach (appContext,...) // Bind the context to the activity and do some initialization work, such as createPhoneWindow Activity. Attach (appContext,...) ; mInstrumentation.callActivityOnCreate(activity,r.state); // Lifecycle OnCreate activity.performStart(); // Lifecycle OnStart return activityCopy the code
  5. HandleResumeActivity:

    -> r.activity.performResume()     
       -> mInstrumentation.callActivityOnResume(this);
         -> activity.onResume()
    Copy the code