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?

  1. 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.

  1. 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

  1. 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!