Android Performance Optimization Series App Startup Optimization

The slow startup speed of applications is a problem we often encounter during the development process, such as black screen and white screen problems caused by slow startup. This blog will introduce the relevant knowledge of App startup optimization.

How to launch the app

Generally speaking, there are two starting methods: cold start and hot start.

1. Cold start: When an 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. This startup method is cold start. In cold start, because the system will re-create a new process and assign it to it, it will first create and initialize the Application class, then create and initialize the MainActivity class (including a series of measurements, layout, and drawing), and finally display it on the interface.

2. Warm start: When starting an application, there is already a process of the application in the background (for example: press the back key and home key, although the application will exit, the process of the application will still remain in the background and can be viewed in the task list) , so if there is an existing process, this startup will start the application from the existing process. This method is called hot start. Because hot start will start from an existing process, hot start will not go through the Application step, but directly go to MainActivity (including a series of measurement, layout, and drawing), so the hot start process only needs to create Just initialize a MainActivity instead of creating and initializing the Application, because the Application will only be initialized once from the creation of a new process to the destruction of the process.

App startup process

The optimizations referred to in this article are for cold starts. Briefly explain the app startup process:

1. Click Launcher to start the program and notify ActivityManagerService

2.ActivityManagerService notifies the zygote process to hatch the application process, allocate memory space, etc.

3. Execute the main() method of the application ActivityThread

4. The application notifies ActivityManagerService that it has been started. ActivityManagerService saves a proxy object of the application through which ActivityManagerService can control the application process.

5.ActivityManagerService notifies the application process to create an entry Activity instance and execute its life cycle

During the startup process, the life cycle methods of Application and entry Activity are called in the following order:

1.Application construction method

2.attachBaseContext()

3.onCreate()

4. Object construction of entry Activity

5.setTheme() sets the theme and other information

6. onCreate() of the entry Activity

7. onStart() of entry Activity

8. onResume() of the entry Activity

9. onAttachToWindow() of the entry Activity

10. onWindowFocusChanged() of the entry Activity

Write picture description here

What is the application startup time

The time from clicking the application’s startup icon to creating a new process until we see the first frame of the interface is the application startup time.

What we want to measure is this period of time. Measuring this period of time can be measured through the adb shell command. This method is the most accurate. The command is:

adb shell am start -W [PackageName]/[PackageName.MainActivity]

1. ThisTime: Generally the same as TotalTime, unless a transparent Activity is opened when the application starts to process some things in advance and then display the main Activity, which will be smaller than TotalTime. 2. TotalTime: The startup time of the application, including process creation + Application initialization + Activity initialization to interface display. 3. WaitTime: Generally larger than TotalTime, including the time consuming affected by the system.

Use TraceView to analyze startup time

Add trace at the beginning and end of onCreate.

Debug.startMethodTracing("TestApp");
...
Debug.stopMethodTracing();

When running the program, buildpath will be called to return the path in Android/data/package name/files. The final result is: storage/emulated/0/Android/data/package name/files/dmtrace.trace Note: Need to add writing to the program Storage permissions:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Export it to local via adb pull

adb pull /sdcard/TestApp.trace ~/testSpeed.trace

Open the DDMS analysis trace file and the following interface will appear.

Write picture description here

Generally, you only need to pay attention to: Calls + Recur Calls/Total and Cpu Time/Call Cpu Time/Call reflects that the number of calls is not many, but each call takes a long time. Calls + Recur Calls/Total reflects that it does not take up a long time. , but a function that is called very frequently

How to reduce the time it takes to start an application

To deal with the time-consuming cold start, the following strategies can be adopted:

1. Do not initialize time-consuming operations in the Application’s constructor method, attachBaseContext(), and onCreate() methods. Some data prefetching is placed in asynchronous threads and can be implemented using Callable. 2. For the initialization of sp, because the characteristic of sp is that all data will be read out and stored in the memory during initialization, so it is not appropriate to place this initialization in the main thread. On the contrary, it will delay the startup speed of the application. For this, it still needs to be placed asynchronously. Processed in thread. 3. For MainActivity, before obtaining the first frame, the contentView needs to be measured, laid out, and drawn to minimize the layout level. Consider the delayed loading strategy of StubView. Of course, avoid time-consuming operations in the onCreate, onStart, and onResume methods. .

Following the above three strategies can significantly improve app startup speed.

Optimize the experience when the application is launched

Regarding the startup time of the application, we can only try to avoid some time-consuming and unnecessary operations in the main thread. This can relatively reduce part of the startup time. On the other hand, while waiting for the first frame to be displayed, you can Add some configurations to enhance the experience, such as adding the background of the Activity. This background will be displayed on the interface in advance before the first frame is displayed. Regarding the startup time of the application, we can only try to avoid some time-consuming and unnecessary operations in the main thread. This can relatively reduce part of the startup time. On the other hand, while waiting for the first frame to be displayed, you can Add some configurations to enhance the experience, such as adding the background of the Activity. This background will be displayed on the interface in advance before the first frame is displayed.

Option 1:

1. First, write a separate theme style for the main interface and set a picture to be displayed. Here I set a color, and then set it to MainActivity in the manifest:

<style name="AppTheme.Launcher">
 <item name="android:windowBackground">@drawable/bule</item>
</style>
//...
  <activity
   android:name=".MainActivity"
   android:label="@string/app_name"
   android:theme="@style/AppTheme.Launcher">
   <intent-filter>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
   </intent-filter>
  </activity>

2. Then reset the AppTheme to MainActivity before loading the layout in MainActivity:

@Override
 protected void onCreate(Bundle savedInstanceState) {<!-- -->
 
  setTheme(R.style.AppTheme);
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
}

In this way, the background will be displayed first when starting, and then the main interface will be displayed after the interface drawing is completed:

Write picture description here

Solution 2: Set the Style (1) Set the background image Theme by setting a background image. When the program starts, this background image is displayed first to avoid a black screen.

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:screenOrientation">portrait</item>
        <item name="android:windowBackground">>@mipmap/splash</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowNoTitle">true</item>
</style>

(2) Set a transparent Theme. By setting the style to transparent, the screen will not be black but completely transparent after the program is started. It will not be displayed until the interface is initialized.

 <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:screenOrientation">portrait</item>
    </style>

Comparison between the two: The Theme1 program starts quickly, the interface first displays the background image, and then refreshes other interface controls. It feels like the refresh is out of sync. Theme2 gives people the feeling that the program starts slowly, the interface is refreshed at once, and the refresh is synchronized. (3) Modify AndroidManifest.xml

 <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true">
        <activity android:name=".MainActivity"
         android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    //......

</application>

For more Android advanced guides, you can Scan the code to unlock “Android Ten Major Section Documents”

1. Android vehicle application development system study guide (with actual project practice)

2. Android Framework study guide to help you become a system-level development expert

3.2023 Latest Android Intermediate and Advanced Interview Questions Summary + Analysis, Say Goodbye to Zero Offers

4. Enterprise-level Android audio and video development learning route + project practice (with source code)

5. Android Jetpack builds high-quality UI interfaces from entry to proficiency

6. Flutter technology analysis and practical implementation, the first choice for cross-platform

7. Kotlin improves the architectural foundation in all aspects from entry to actual use

8. Advanced Android plug-in and componentization (including practical tutorials and source code)

9. Android performance optimization practice + 360° all-round performance tuning

10. From beginner to proficient in Android, the path to advancement for experts

It’s not easy to code, so pay attention. ?( ′?` )