An article to get the "APP startup process"

foreword

The drawing process of Binder, Handler, and View has been laid out before,
so it's time to look at the startup process of the APP, how to start these important components of ours.
This article will explain the steps and members required for startup with a little source code.
Focus on understanding and familiarizing with the startup process. Will not use the source code in depth.
The structure of this article:
1. Cold start, warm start, hot start
2. Introduction to important members in the start-up process
3. Detailed explanation of the start-up steps
4. Start-up optimization (discussion)

Cold start, Warm start, Hot start

  • Cold start: When the application is started, there is no process of the application in the background. At this time, the system will re-create a new process and assign it to the application, and then start the corresponding process component according to the startup parameters. This startup method is cold start.
  • Warm start: When the application is started, there is already a process of the application in the background, but the Activity may be recycled due to insufficient memory. In this way, the system will start the Activity from the existing process. This startup method is called warm startup.
  • Hot start: When the application is started, there is already a process of the application in the background (for example: press the back key, home key, although the application will exit, but the process of the application will still remain in the background, you can enter the task list to view), so In the case of an existing process, this kind of startup will start the corresponding process component from the existing process. This method is called hot startup.

Compared with other startup methods, cold start requires more process creation (Zygote process fork creation process) and application resource loading and initialization (Application creation and initialization), so it will be relatively time-consuming, so we generally say App Startup optimization generally refers to the cold start optimization of the App.
important in startup

Profiles of Key Members in the Startup

zygote process

Not to mention the high-sounding ones, but simply summarize two things for everyone:

  • The zygote process is a process from the init process and fock in Linux.
  • In Android, all application processes are forked by the zygote process, and a new App process is a child process of the zygote process.

The Zygote process will first fork the SystemServer process hatched by itself, and its main function is mainly responsible for:

  • Start the binder thread pool, which is the basis for SystemServer to communicate with other processes
  • Initialize Looper
  • A SystemServiceManager object is created, which will start various services in Android. Including AMS, PMS, WMS
  • Start the desktop process so that the user can see the interface of the mobile phone.
  • Open the loop cycle, open the message loop, and the SystemServer process runs all the time to ensure the normal operation of other applications.

Note: The init process is created when it is turned on, so our zygote process and ServiceManager are created when it is turned on.

Instrumentation

Tool class, which is used to monitor the interaction between the application program and the system, and wraps the call of ActivityManagerService. Some plug-in solutions are implemented through the hook class.

SystemServer process

SystemServer is the first process forked by the zygote process. SystemServer and Zygote are the two most important processes of the Android Framework. All important services in the system are started in this process, such as ActivityManagerService, PackageManagerService, WindowManagerService.
The application startup process basically revolves around ActivityManagerService and ActivityThread.

ActivityManagerService

  • In the Android system, the startup of any Activity is completed by the cooperation of AMS and App process (mainly ActivityThread).
  • He is initialized after the SystemServer is created
  • App process and AMS perform cross-process communication through Binder mechanism
  • AMS (SystemServer process) and zygote communicate across processes through Socket.

Binder

Binder will not go into details, IPC cross-process communication in the Android system.
It is the content in "One Article Gets <Binder>"

ActivityThread

ActivityThread is the main thread that drives the application in the Android system, and its role is to manage the life cycle and interaction of the application. ActivityThread is responsible for starting the application's entry Activity, providing a communication bridge with the Android system, and also handling the application's message queue and event loop.
During the startup process of App, ActivityThread is mainly responsible for the following important tasks:

  • Create a main thread Looper for processing message queues and event loops.
  • Load the application's theme, resources, and layout files.
  • Trigger the application life cycle by calling Instrumentation's callApplicationOnCreate() method, initialize the application, and create the first Activity.

Detailed steps to start

The red line in the figure is Binder communication,
and the purple line is Socket communication

1. Click the desktop icon

  • Launcher captures the click event and calls Activity#startActivity();
  • Clicking the icon occurs in the process of the Launcher application, and the startActivity() function is finally sent by Instrumentation to the system_server process through the Binder cross-process communication mechanism of Android;
    insert image description here

Two, create a process

In system_server, the operation of starting the process will first call the ActivityManagerService#startProcessLocked() method, which internally calls Process.start(android.app.ActivityThread); and then inform the Zygote process to fork the child process, that is, the app process, through socket communication.
insert image description here

3. Initialize the APP process

  • Start the main thread After the app process starts, it first instantiates the ActivityThread and executes its main() function
  • Create ApplicationThread, Looper, and Handler objects in the main() function, and open the main thread message loop Looper.loop().
  • Call ActivityThread#attach(false) method for Binder communication

The source code is as follows: ActivityThread.java

public static void main(String[] args) {
···
     Looper.prepareMainLooper();

     ActivityThread thread = new ActivityThread();
     thread.attach(false);

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


 private void attach(boolean system) {
 ···
     if (!system) {
     ···
         final IActivityManager mgr = ActivityManager.getService();
         try {
             mgr.attachApplication(mAppThread);
         } catch (RemoteException ex) {
             throw ex.rethrowFromSystemServer();
         }
     ···
     } else {
    ···
     }
 ···
 }

insert image description here

4. Binding of APP process and System_server

  • Call the ActivityThread#attach(false) method for Binder communication (the next step in the method)
  • Notify the system_server process to execute the ActivityManagerService#attachApplication(mAppThread) method
  • After receiving the request, the system_server process performs a series of preparatory work (creating the App process information table) and then sends a scheduleLaunchActivity request to the App process through the binder IPC;
  • This is equivalent to the APP process sending information to the system_server process for a binding process. The process of creating a communication.
    insert image description here

5. Initialize Application And Activity

  • After receiving the request, the binder thread (ApplicationThread) of the App process sends a LAUNCH_ACTIVITY message to the main thread (ActivityThread) through the handler;
  • After receiving the Message, the main thread (ActivityThread) creates the target Activity through HandleLaunchActivity, and calls back methods such as Activity.onCreate().
  • At this point, the App is officially launched and enters the Activity life cycle. After executing the onCreate/onStart/onResume methods, you can see the main interface of the App after the UI rendering is complete. So far, the
    insert image description here
    startup process of the App is over, and the above picture is also complete. The start-up process model diagram.

Startup optimization (discussion)

Transparent theme optimization

In order to solve the problem of the white screen of the startup window, a transparent theme is used to solve this problem, but it does not cure the root cause.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowIsTranslucent">true</item>
</style>

Set the splash screen image theme

This is a lot of apps that are still in use.
In order to seamlessly connect our splash screen page, you can set the splash screen page picture in the Theme of the startup Activity, so that the picture of the startup window will be the splash screen page picture instead of white screen.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@mipmap/launch_image</item>   //闪屏页图片  
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

If this is set, the picture of the splash screen page will be displayed during cold start, and the connection can be seamless after the App process initializes and loads the entry Activity (also the splash screen page).
In fact, this method does not really accelerate the startup speed of the application process, but only optimizes the experience brought by the user's visual effects.

Application optimization

Through the above process, we can know. We will initialize our Application first, so initializing in Application to reduce time-consuming operations can effectively help me improve.
Often there are opportunities to optimize these efforts for performance improvements, these common issues include:

  • Complicated and cumbersome layout initialization
  • Operations that block UI drawing on the main thread, such as I/O read and write or network access.
  • Bitmap large picture or VectorDrawable loading
  • Other operations that occupy the main thread

Many third-party components (including the App application itself) take the lead in the Application to complete the initialization operation.
Such as Bugly, x5 kernel initialization, SP reading and writing, Youmeng and other components. Then put it in the child thread to initialize.

Splash page business optimization

For example, actions such as point burying, click stream, database initialization, etc. must be initialized on the main thread. Then we can put it on the splash screen page.
General: total display time of the splash screen page = component initialization time + remaining display time.
That is, the total time is 2000ms, and the component is initialized for 800ms, then it can be displayed for another 1200ms.

Through the above process analysis, we can know that after the Application is initialized, it will call the attachBaseContext() method, then call the Application's onCreate(), and then create and execute the onCreate() method of the entry Activity. So we can record the startup time in Application.
Application.java

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    SPUtil.putLong("application\_attach\_time",
        System.currentTimeMillis());//记录Application初始化时间  
}

With the startup time, we need to know the time when the Acitivty of the entrance is displayed to the user (the View is drawn)
that is the onWindowFocusChanged of the entrance Activity.
Entry Activity.java

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    long appAttachTime = SPUtil.getLong("application\_attach\_time");
    long diffTime = System.currentTimeMillis() - appAttachTime;
    //从application到入口Acitity的时间  
    
    //所以闪屏页展示的时间为 2000ms - diffTime.  
}

Using Hook

  • ActivityManagerService

In the Android system, the process of starting an application is usually managed through ActivityManagerService. You can perform some optimization operations when the application starts by means of Hook ActivityManagerService. For example, you can create an empty Activity before the application starts, and perform some time-consuming operations in its onCreate method, such as initializing data or preloading resources. Then, through the Hook ActivityManagerService, replace the started Activity with this empty Activity form, which can reduce the time-consuming application startup.

  • AMS and PMS

During the process of application startup, the Android system will perform permission verification and security check on the startup of components such as Activity and Service. This process is time-consuming, and these checks can be bypassed through Hook ActivityManagerService (AMS) and PackageManagerService (PMS), thereby increasing the startup speed. For example, you can use Hook AMS and PMS to modify the application startup process, skip the process of permission verification and security check, thereby reducing the startup time.

Summarize

There is a lot of knowledge about the startup process of APP. A certain understanding of the source code of Android is required.
But we need to consciously pay attention in development that will affect the operation launched by APP.
After all, the startup of APP is the first door.

Guess you like

Origin blog.csdn.net/weixin_45112340/article/details/131927752