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 a ViewStub

  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 1: use 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 area of concern for now is what’s 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.

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: Rearrange 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.

So we set out to do three things:

1) Install and configure Redex

2) Get the loading order of the class files during startup

3) Rearrange the class files in dex in this order

Specific steps

1) Download Redex and configure the environment (Mac OS)

git clonehttps://github.com/facebook/redex.git xcode-select --install brew install autoconf automake libtool python3 brew install  boost jsoncppCopy 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 done'

Copy the code

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 the last Activity

TotalTime: the TotalTime it takes to start a sequence 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.

Cold start process and some concepts about Android App can refer to Google official document “App startup time” developer.android.com/topic/perfo…

For some reasons, there are some optimization methods are not in practice, interested in their own understanding:

1) GC optimization in ** 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, ** minimize CPU scheduling, specifically to control the number of threads and scheduling

3) ** Remove the class validation process by Hook during the class loading process. ** You can see the verifyClass process in the files generated by Systrace. Because it needs to verify every instruction of the method, it is a time-consuming operation.

Android learning PDF+ architecture video + interview document + source notes

The last

Thank you for sitting through this article.

Here I also share a self-collected and organized Android learning PDF+ architecture video + interview document + source notes, and advanced architecture technology advanced brain map, Android development interview topic information, advanced architecture information to help you learn to improve the advanced, but also save you on the Internet search information time to learn, You can also share it with your friends to learn together

If you have the need, you can like, follow me, and then pay attention to the wechat public number [Android development home] for free