Performance optimization has always been a hot topic for Android developers, and startup optimization is especially important. Launch speed can have a direct impact on an App’s retention and conversion rate, and no one wants to wait a while to open an App after clicking on it.
But when I did some research, I found that most of the online startup optimization related articles, routine is similar, I call it the old three.
What is old third kind?
- Set the splash page theme background to a splash page image
The main purpose of this is to eliminate the black and white screen at startup and give the user the feeling of a second response, but it doesn’t really reduce the user’s startup time, it’s just a visual optimization.
- Home page layout optimization
1) Reduce the view hierarchy by reducing redundancy or nesting layouts 2) Replace UI controls that do not need to be displayed during startup with viewStubs
- Some code is initialized asynchronously in the onCreate of the Application and main Activity
Because resource initialization on the main thread slows startup, it can be optimized by delaying unnecessary resource initialization. But here to pay attention to the problem of lazy loading centralization, other users start time is fast, but can not operate on the interface is embarrassing.
The old three is not to say that it does not work or out of date, but these three optimization methods are very basic, when your startup optimization encountered a bottleneck, is not able to break through these three ways.
And they’re just basic optimizations that don’t show up on a resume.
So today, what are the feasible solutions based on the optimization of the old three.
Advanced scheme one uses Systrace to find time-consuming code
Specific steps
1) Clear the background of your phone
2) Execute it on the command line
python $ANDROID_HOME/platform-tools/systrace/systrace.py gfx view wm am pm ss dalvik app sched -b 90960 -aYour package name -o test.log.htmlCopy the code
This step requires that your system environment has configured the ANDROID_HOME environment variable.
3) Run your App, proceed to the place where you want to measure performance normally, and then press Enter in the command line window to stop collection
4) Open the generated test.log. HTML result file with Chrome (this browser is only supported), and the result is shown as follows:
The areas of concern for now are the areas that are relevant to our application process, which is circled in red.
In the figure, F represents the drawing frame, yellow/red represents the drawing timeout, and green represents the normal drawing, that is, a frame is drawn within 16.6ms.
For information on how to use Systrace, see this article
Zoom in to see how long the control takes to render during startup
So it’s easy to see which UI controls are rendered that were not used during startup, and you can use the ViewStub instead.
But now all you can see is the time spent on system calls, because Google has pre-installed monitoring at key points in the code, and if you want to see the time spent on your method,
You need to manually add Trace. BeginSection (“TAG”) to the method entry.
Add trace.endSection () to the end of the method
This allows you to see our custom tag in the generated result.
If you want to add monitoring in many places, manually adding is definitely not appropriate, here recommended function piling automatically add monitoring code, refer to systrace+ function piling
Not only can this help monitor performance issues during startup, but it can also be used when doing lag optimizations.
Once the time consuming method is located, it is relatively easy to do some targeted optimizations.
Advanced solution 2 rearranges class files using Redex
Redex is Facebook’s open-source bytecode optimization tool, currently only available for MAC and Linux.
We use interdex to rearrange class files in our dex, so why does rearranging class files optimize startup speed?
To put it simply, the purpose of file rearrangement is to arrange the files needed in the startup phase together in APK files. The pagecache mechanism of the Linux file system can be used as much as possible to read as many files needed in the startup phase with the minimum disk I/O times and reduce I/O overhead. In order to achieve the purpose of improving the startup performance.
For details, please refer to alipay’s article “Optimizing Android Startup Performance through Package Rearrangement”.
So we set out to do three things:
1) Install and configure redex. 2) Obtain the loading order of the class files during startup. 3) Rearrange the class files in dex according to this order
Specific steps
1) Download Redex and configure the environment (Mac OS)
git clone https://github.com/facebook/redex.git
xcode-select --install
brew install autoconf automake libtool python3
brew install boost jsoncpp
Copy the code
2) Compile and install Redex
cd redex
autoreconf -ivf && ./configure && make
sudo make install
Copy the code
If you don’t want to wait for a long time to compile, you can add the say command to voice notification after compiling
Autoreconf - IVF &&./configure && make && say 'compile complete'
3) Configure optimization items
Because Interdex is not enabled by default in Redex, we need to add the corresponding configuration to the configuration file, which is explained in the Redex document
So we open the configuration file
cd redex/config/
vi default.config
Copy the code
Configuration as shown in the following figure
4) Get the list of boot class loading order
You can obtain it by following the tool provided by Redex, but the mobile phone must have root permission
Clear background processes first, then open your app
Get the PID of your application
The adb shell ps | grep your application package nameCopy the code
To collect heap memory, root permission is required
adb root
adb shell am dumpheap YOUR_PID /data/local/tmp/SOMEDUMP.hprof
Copy the code
Pull the heap memory file to a location on the computer
adb pull /data/local/tmp/SOMEDUMP.hprof YOUR_DIR_HERE/.
Copy the code
The heap memory is parsed by a Python script to generate a list of the class loading order
python redex/tools/hprof/dump_classes_from_hprof.py --hprof YOUR_DIR_HERE/SOMEDUMP.hprof > list_of_classes.txt
Copy the code
Ps: This script supports Python 2. If you encounter a library that is not installed, you can simply use PIP install to install the missing library
5) Process through Redex
ANDROID_SDK= Your Android SDK path redex input.apk -o output.apkCopy the code
6) Re-sign
At this time, the generated output.apk cannot be installed directly and needs to be re-signed. I used the Debug package for testing, so I re-signed the debug signature
jarsigner -keystore ~/.android/debug.keystore -storepass android -keypass android output.apk androiddebugkey
Copy the code
From there, you can re-install and test. According to Facebook and some of the big manufacturers, the startup speed is about 10% to 20% faster, and it should be more noticeable on low-end models.
The use of Redex and related configuration documents can be viewed in the redex/docs/ directory.
Other related
Start-up time measurement
In order to correctly diagnose the performance of cold start, a cold start time indicator is needed. There are two simple ways to do this:
Adb command: ADB shell am start -s -w
Such as:
adb shell am start -S -W com.android.helloword/com.android.helloword.MainActivity
Copy the code
- ThisTime: start time of last Activity (e.g. LaunchActivity – >MainActivity “adb input Activity”, count MainActivity start time only)
- TotalTime: the TotalTime it takes to start a series of activities.
- WaitTime: application process creation + TotalTime
So let’s just focus on TotalTime.
Google also provides measurements in Android4.4 (API 19) by filtering the Displayed field in logcat,
The output value represents the elapsed time between the start of the Activity and the completion of drawing the Activity on the screen, which is the same as the above method.
For details about the cold startup process of Android apps and some concepts, please refer to the official Google document “App Startup Time”.
For some reasons, there are some optimization methods are not in practice, interested in their own understanding:
1) GC optimization during startup process, minimize the number of GC, avoid creating a large number of or frequent objects, if necessary, try to put into Native implementation
2) Thread optimization, reduce CPU scheduling as much as possible, specifically to control the number of threads and scheduling
3) In the process of class loading, remove the process of class verification by Hook. You can see the verifyClass process in the files generated by Systrace. It is a time-consuming operation because every instruction of the method needs to be verified
The above is my summary of Android cold start optimization, the level is limited, it is inevitable that there are inaccurate places, welcome to correct.
This article was first published on the public account “Houzhihoujue”, wechat search attention reply “1024”, you know!