Yang Master (ID: CY_YANG_DA_YE) is a developer and sharer focusing on the Android field.Copy the code
background
The new version of our APP has been two and a half years since the submission of the first line of code in April 2017. In the past two years, the content of the APP has been constantly enriched, such as adding modules of job hunting and recruitment, Q&A, personal center, second mobile phone, small video and so on. At the same time, the old functions are constantly improved. For example, the contents of posts are enriched, the details page of small videos is as convenient as Douyin, and the aggregation of tags is more accurate to attract users.
In addition to rich functions and contents, it will inevitably introduce many third-party tools, such as Umeng, Getui, Shence, Tencent cloud’s video component, IM instant messaging component, GreenDao database and so on
With the increasing amount of code, more and more third-party tools lead to a long time and poor user experience when the APP is launched for the first time.
Nimbledroid estimates the average cold startup time for Google Play apps by category (Nexus 5 + Android 4.4) [Image upload failed…(image-c82b9A-1565334335822)] For the top 100 non-game apps in Play, the cold launch time is
39 cold start times within 2 seconds
73 cold start times within 3 seconds
The cold startup time of our APP is:
Execute command line
The adb shell am start - W - n package name/package name. The activity. MainEntryActivityCopy the code
ThisTime: how long it took for the last Activity to start;
TotalTime: the startup time of all your activities;
WaitTime: The total time that ActivityManagerService starts the App’s Activity (both the onPause() of the current Activity and the start of its own Activity).
That is, at boot time, it takes 2.4 seconds.
So there’s a lot of room for improvement.
Next, through the content of this article, an in-depth analysis of the cause of slow start, and give a reasonable solution.
Start-up process analysis
To start, optimize the startup process, so we need to first understand, The Android system, in the startup process of an APP is what? What did you do?
Cold start, hot start
Cold start: When an application is started, the system creates a new process and assigns it to the application.
Hot start: When an application is started, it is started from an existing process (the back button, the home button, the application exits but is not destroyed) that exists in the background.
Because hot start is the background process already exists, so the startup speed is relatively fast, and the optimization mentioned here refers to cold start.
The Android cold start process is relatively complex, requiring 35 steps, or five steps to simplify
The entire application startup process involves many steps, but as a whole, it can be divided into the following five stages: 1. Step1-step 11: The Launcher notifies the ActivityManagerService through the Binder interprocess communication mechanism that it wants to start an Activity. ActivityManagerService sends the Launcher to Paused state through the Binder interprocess communication mechanism. Step 17 - Step 24: The Launcher uses the Binder interprocess communication mechanism to tell ActivityManagerService that it is ready to go to Paused, and ActivityManagerService creates a new process, It is used to start an ActivityThread instance in which the Activity to be started will run. Step 25: ActivityThread passes a Binder object of type ApplicationThread to ActivityManagerService through the Binder interprocess communication mechanism. So that ActivityManagerService can later communicate with the Binder object; The ActivityManagerService notifies the ActivityThread through the Binder interprocess communication mechanism that it is now ready to actually start the Activity.Copy the code
At a simpler level, from the moment the user clicks on the desktop icon, the following process roughly takes place:
During this startup process, there may be several problems:
1. No response after clicking the icon for a long time.
2. The home page is too slow.
3. Operations cannot be performed after the home page is displayed.
And then, the key problem to solve is that clicking on the icon does not respond for a long time.
Optimization tools
When encountering a problem, there are no more than the following steps to the final solution.
Hugo is a tool developed by Jake Wharton. It prints the execution time of each method in the log, which helps us locate methods and functions with long running time and is relatively easy to configure.
Next, try it out in code.
I wanted to look at the initialization time in the Application
@DebugLog
@Override
public void onCreate(a) {
super.onCreate();
initHttpClient();
// // Perform initial configuration
initGlobal();
// CrashCaptureHandler.getInstance().initCrashHandler();
initJPush();
initGetTuiPush();
initSource();
initSmallVideoRecord();
initIM();
if (BuildConfig.DEBUG) {
boolean hostUrlEnable = new HostUrlUtils().initHost(URLConstants.class.getDeclaredFields(), URLConstants.RELEASE_SERVER);
if(hostUrlEnable) { Dispatcher.hostUrlClass = URLConstants.class; }}else {
// Crash protection starts in the official environment
install();
initAliyunLog();
}
initHuoDongHeZi();
initSensor();
initUmeng();
initLinkMe();
initRN();
}
Copy the code
Look at the printed Log
/> V/MyApplication: ⇢ onCreate() 2019-08-10 16:10:09.941 30678-30678/? V/MyApplication: ⇢ onCreate() 2019-08-10 16:10:004 30692-30692/? V/MyApplication: ⇢ onCreate() 2019-08-10 16:10:10.124 30737-30737/? V/MyApplication: ⇢ onCreate() 2019-08-10 16:10:10.529 30678-30678/? V/MyApplication: ⇠ onCreate [587ms] V/MyApplication: ⇠ onCreate [516ms] 2019-08-10 16:10:10.832 30737-30737/? V/MyApplication: ⇠ onCreate [707ms] 2019-08-10 16:10:10.881 30692-30692/? V/MyApplication: ⇠ onCreate [577ms] 2019-08-10 16:10:13.917 31109-31109/? :xg_service_v3 /MyApplication: ⇢ onCreate() 2019-08-10 16:10:14.441 31109-31109/? : xg_service_vv /MyApplication: ⇠ onCreate [524ms]Copy the code
As you can see, initializing onCreat is called multiple times!
In normal cases, an application will start a process, so the application will be executed once, which means that during the startup process, the initialization time will be 2391ms because of repeated initialization calls. This greatly affects the startup speed of APP! Used to give the feeling that there is no response after clicking the icon.
To solve the problem
Now that the problems have been identified, they must be solved.
Since the discovery is a process problem, it is important to look at what processes are involved in the startup process.
2019- 08 -10 16:40:07.881 3166-3166/? D/yzc: ?
2019- 08 -10 16:40:07.978 3225-3225/? D/yzc:? :pushcore2019- 08 -10 16:40:08.128 3298-3298/? D/yzc:? :ipc2019- 08 -10 16:40:08.172 3245-3245/? D/yzc:? :pushservice2019- 08 -10 16:40:11.754 3739-3739/? s:xg_service_v3 D/yzc: ? s:xg_service_v3
Copy the code
It can be seen that in addition to APP process, there are also carrier pigeon push process, IPC process, individual push process, aurora process.
Before, some businesses may need to integrate the push of three, and each push will silently open a process in the background to receive the push message. This will naturally cause the APP’s first initialization to start slowly.
Confirmed with the operation partner, currently only carrier pigeon push is in use, push, aurora will be removed. So once you get rid of that, look at the boot time.
It also avoids multiple initializations!
800ms optimized compared to the previous 2391ms! Next, continue to optimize and see where there is room to optimize.
Continue to optimize
Application initializes optimization
In Application, you can see that the initialized content is
initGlobal(); InitIM (); Initialize instant communication initSource(); InitSmallVideoRecord (); Initialize short video install(); Init in Crash initAliyunLog(); Initializing aliyun content initHuoDongHeZi(); Initialize the active box initSensor(); Initialize initUmeng(); Initialize initLinkMe(); Initialize the deep connection initRN(). Initialize ReactNative
Take a separate tally of how long each initialization takes.
initBbsGlobal [73ms]
initIM [95ms]
initSource [0ms]
initSmallVideoRecord [11ms]
install [0ms]
initAliyunLog [19ms]
initHuoDongHeZi [69ms]
initSensor [191ms]
initUmeng [14ms]
initLinkMe [63ms]
initRN [0ms]
According to the statistics, you can see that the methods that take a long time are strategy, IM chat, active box, deep connection, configuration file. For these long times, without affecting the function, you can try to initialize them in the child thread, without occupying the main thread resources.
new Thread(new Runnable() {
@Override
public void run(a) {
initIM();
initSource();
initSmallVideoRecord();
initLinkMe();
initUmeng();
if(! URLConstants.RELEASE_SERVER) {boolean hostUrlEnable = new HostUrlUtils().initHost(URLConstants.class.getDeclaredFields(), URLConstants.RELEASE_SERVER);
if(! hostUrlEnable) {new AlertDialog.Builder(getApplicationContext())
.setTitle("No available URL detected")
.setMessage("Please make sure the URL is available.")
.setPositiveButton("Quit".null).show();
}
Dispatcher.hostUrlClass = URLConstants.class;
} else {
// Crash protection starts in the official environment
install();
initAliyunLog();
}
initHuoDongHeZi();
}
}).start();
Copy the code
After modification, take a look at the startup time.
Compared to the previous optimization and 300ms! , compared with 1132ms optimized before no optimization! That is, faster than a second of time, can say that the effect is still very obvious.
At the same time, it can be seen that the initialization time of Application is currently only 199ms
MainEntryActivity initialization optimization
At the end of Application optimization, take a look at MainEntryActivity. This Activity is an Activity that enters the app, and in the onCreate() of this Activity, it makes some requests, Let’s see if there’s anything we can do to make it better.
In this case, there are two operations that take a long time, one is
isCityInviteNetWork()
This method is when the user logs in, according to the user to obtain the user’s location information and store.
This method can be placed in a child thread without using resources from the main thread.
checkAdversiterment()
This is the way to get an open screen AD on the network, and this requires the interface to get the open screen AD and display it.
For this method, it is also possible to operate asynchronously in the child thread, caching the first request and displaying it from the second entry to the APP, thus avoiding the time-consuming operation of the main thread.
After these operations, you can see that the startup time has been optimized to about 1s.
The last
Although, there is no current second on effect, but compared with the optimization before there has been a great difference, optimization effect. In the future, will continue to optimize, strive to achieve a better effect.
Before, I saw a friend said that you can set the theme to achieve the effect of opening in seconds, I tried it, it seems not very good, also need about 500ms, if you have good ideas and suggestions, welcome to leave a message to me! Let’s discuss!
Reference: www.jianshu.com/p/e69d22ec0… www.jianshu.com/p/1e65aa223… www.jianshu.com/p/496529bd1… Blog.csdn.net/u013263323/…