1. Overview
Performance optimization is an important knowledge in Android and an important basis for measuring the level of an Android engineer. Many people may know simple performance optimization. For example, many people must know the following methods to optimize UI rendering:
-
Use “Settings –> Developer Options –> Debugging GPU overdrawing” to distinguish whether there is overdrawing based on the different colors displayed on the screen, so as to check the xml file of the interface, remove unnecessary background, and eliminate overdrawing.
-
View the layout hierarchy through Layout Inspector to check whether there are multiple levels of useless nesting (since Hierarchy Viewer has been deprecated, if you use Android Studio 3.1 and newer, it will be more convenient to use Layout Inspector to view the layout)
-
Use ViewStub & amp; merge tags in xml to optimize layout hierarchy
-
…
The above points are of course important, but to some extent, the above methods are no longer enough, and we need to use other methods to optimize performance.
As the saying goes, if you want to do your job well, you must first sharpen your tools. Using a good tool can certainly help us get twice the result with half the effort. Due to the severe runtime overhead of TraceView, many data measured by TraceView have large deviations, so Google now Strongly recommend systrace, systrace is a very powerful performance analysis tool.
Systrace can collect and analyze the time information of all processes when the device is running at the system level. It collects information from the Android kernel, such as CPU scheduling, disk activity and app threads, and then generates an html file as shown in the figure below. It should be noted that the generated trace.html file must be opened with the Chrome browser before it can be browsed and used normally.
Image source: systrace. As shown in the picture above, each small circle in the ‘Frames’ line represents each frame, and different colors are used to represent normal rendering. If a certain small circle is represented by yellow/red, it indicates that this frame There may be a problem with the rendering of
Okay, let’s take a look at how to use the systrace tool
2. How to use
I use a Mac computer, so the following operations are performed on a Mac, and they should be similar on a Windows system.
2.1 Preparation
Before using systrace, you need to do the following preparations
-
Newer Android SDK Tools
-
Requires the cooperation of the PC side. Python is installed on the PC side and configured in the system environment variables.
-
The device for debugging needs to be 4.3 (API Level 18) or above. The higher the system, the more information can be collected, which is more conducive to analysis. The application for analysis needs to be a debug package.
-
The Android device and PC are successfully connected via USB and are in a debuggable state.
At this point, the preparation work has been completed
2.2 Use
2.2.1 How to use
Enter the /Android/sdk/platform-tools/systrace/ directory through Terminal
At this time, operate the application on the device to bring the application into a state to be debugged. For example, if you need to debug a certain page RecyclerView, enter the page.
Then run the following command in Terminal, where [options] [categories]
are all parameters that need to be entered.
./systrace.py [options] [categories]
For example, execute the following command, where -o mynewtrace.html -t 10
belongs to the [options]
parameter, sched freq idle am wm gfx view binder_driver hal dalvik camera input res
belongs to the [categories]
parameter
./systrace.py -o mynewtrace.html -t 10 sched freq idle am wm gfx view binder_driver hal dalvik camera input res
After running for 10 seconds, the recorded device activity will be generated into a file named mynewtrace.html.
2.2.2 Parameter Description
So what parameters do [options]
and [categories]
include?
[options]
The parameters are fixed, and commonly used ones include the following
options | Abbreviation | Meaning |
---|---|---|
-o |
None | Specifies the output file, such as: -o mynewtrace.html . If this parameter is not specified, the default name of the file is trace.html |
–time= |
-t |
Specify the duration of systrace, such as -t 10 , which means recording for 10 seconds. The unit of Enter is pressed |
–buf-size= |
-b |
The buffer of the specified systrace is N kb. Specify the total capacity of data collected during the systrace process |
–app= |
-a |
Specify a specific application, such as: -a com.lijiankun24.shadowlayout . If Trace.beginSection("tag") and Trace.endSection are used in this application, these tags will not take effect by default unless you pass this The command specifies the application, and only the information about the method marked by the tag will be recorded in the html file output by systrace |
Before introducing the [categories]
parameter, let’s introduce two useful instructions of systrace
Global options | Abbreviation | Meaning |
---|---|---|
–help | -h | View help information |
–list-categories | – l | Because different devices have different Android system versions, the supported [categories] parameters are also different. You can use this command to see which [categories] parameters are supported by the connected device |
For example, the Android system of my device is Android 7.1.2. After running the following command, you can get the [categories]
parameter information as shown in the figure below.
./systrace -l
The above [categories]
parameters indicate which modules this device supports that can be recorded. The following modules are commonly used.
categories | Full name | Meaning |
---|---|---|
sched | CPU Scheduling | CPU scheduling information, you can see what threads are executed by each core of the CPU at a specific point in time |
gfx | Graphics | Graphics rendering system, including SurfaceFlinger, VSync, Texture, RenderThread information |
input | Input | Input event system, records keyboard input, touch and other event information |
view | View System | View view system, common View onMeasure, onLayout, onDraw are all recorded in this system |
wm | Window Manager | WindowManager’s calling information is recorded in this module |
am | Activity Manager | ActivityManager’s calling information Recorded in this module |
dalvik | Dalvik VM | Virtual machine related information, such as GC garbage collection information |
Generating the trace.html file is probably like this, it is not complicated. Here are some shortcut keys for viewing this html file. Through the following common shortcut keys, you can easily view the html file.
Shortcut keys | Meaning |
---|---|
W | Zoom in timeline |
S | Zoom in timeline |
A | Move the timeline left |
D | Move the timeline right |
Right Arrow | Select the next event on the selected timeline |
Left Arrow | Select the previous event on the selected timeline |
3. Analysis trace.html
3.1 Simple analysis of trace.html file
How do we analyze the generated trace.html file?
As shown in the figure below, it is an enlarged partial view of trace.html. We all know the concept of 60 fps in the Android system, that is, 60 frames will be rendered in 1 second, and it takes 16.6 ms to render one frame. Each frame is framed in red in the picture below. If the rendering is completed within 16.6 ms, then The frame is green, if it takes more than 16.6 ms to render, it will appear yellow or red
Image source systrace
In the picture above, after selecting the problematic yellow frame, you need to pay attention to two parts, as shown below
-
In the first red box, the highlighted part is which methods are called in this frame in the UI thread and RenderThread thread.
-
The second red box displays some information, including the very useful reason for the frame problem (Alert & Description). These are existing problems and optimization suggestions given by the system.
If we select the Alerts tab in the upper right corner in the picture above, the information shown in the picture below will appear, which tells us the frequency of the problem during this period, such as the picture below : Inefficient ListView recycling/rebinding
appears 55 times in total.
You can think of the Alerts tab as a list of bugs that need to be dealt with. The problems in this list all cause problems to our frame rendering to varying degrees. Sometimes it may be just a few lines of code with minor changes and optimizations, but it can solve many of our problems.
3.2 Add Trace information to your application
By default, systrace can only record and collect system-level information, such as WindowManager
, ActivityManager
, and Dalvik and other modules. Is there any way to also record and collect itself? What about some information in the application?
Android provides such an API. This class is the Trace
class. It is not difficult to use the Trace
class to record information in your own application. As shown below, there are the following Points need attention
-
Trace.beginSection(String sectionName)
andTrace.endSection()
need to appear in pairs to ensure that eachTrace.beginSection(String sectionName)
There will be correspondingTrace.endSection()
. It is recommended to usetry {…} finally {…}
-
If there are multiple
Trace.beginSection(String sectionName)
beforeTrace.endSection()
,Trace.endSection()
will match the one closest to it An unmatchedTrace.beginSection(String sectionName)
-
Trace.beginSection(String sectionName)
andTrace.endSection()
need to be in the same thread
public class CardViewListActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Trace.beginSection("CardViewListActivity_onCreate"); try { setContentView(R.layout.activity_card_view_list); RecyclerView recyclerView = findViewById(R.id.rv_card_view); recyclerView.setLayoutManager(new LinearLayoutManager(CardViewListActivity.this)); recyclerView.setAdapter(new CardViewListAdapter()); } finally { Trace.endSection(); } } private static class CardViewListAdapter extends RecyclerView.Adapter<CardViewHolder> { @NonNull @Override public CardViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { Trace.beginSection("CardViewListAdapter_onCreateViewHolder"); CardViewHolder viewHolder; try { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_card_view_list, null); Trace.beginSection("CardViewListAdapter_onCreateViewHolder_newHolder"); try { viewHolder = new CardViewHolder(view); } finally { Trace.endSection(); } } finally { Trace.endSection(); } return viewHolder; } … } … }
After adding the above code to your own application code, it is not over. There is another very important point. When executing the systrace command, you need to specify the application package name through -a
, so that it will be recorded. , collect the trace information added in your application, as shown below:
./systrace.py -t 10 -o mytrace.html -a com.lijiankun24.shadowlayout sched freq idle am wm gfx view binder_driver hal dalvik camera input res
In the generated trace.html file, you can find the sectionName by searching in the upper right corner, and then you can find the record information of the Trace.
3.3 Brief analysis of principles
In fact, the idea of systrace is very simple, which is to log in some critical paths. Through the start and end of the log, you can get the execution time information of a method, and then collect these logs to get the running time information of the critical path, and then Obtain operational performance information of the entire system.
Log through different methods or classes in Android applications, Android Framework and native layers
3.3.1 Android Framework
import android.os.Trace; Trace.traceBegin(long traceTag, String methodName) Trace.traceEnd(long traceTag)
For example, the internal class H.handleMessage(Message msg)
method in ActivityThread
is as follows
In the Android Framework, logging is done through the Trace.traceBegin(long traceTag, String methodName)
method. The passed in traceTag is a constant class in the Trace
class, as shown below
In fact, the Trace
constant value here is the same as the [categories]
value passed in when we execute ./systrace [options] [categories]
corresponding
3.3.2 Android Applications
The corresponding traceTag name is TRACE_TAG_APP
. When running with the systrace.py command, you need to specify the package name of the application through -a
before you can collect buried trace tags. tag
import android.os.Trace; Trace.beginSection(String sectionName) Trace.EndSection()
The source code of the Trace
class is as follows, you can see traceBegin(long traceTag, String methodName)
, traceEnd(long traceTag)
, beginSection(String sectionName) )
, endSection()
finally called the native methods nativeTraceBegin(long tag, String name)
and nativeTraceEnd(long tag)
public final class Trace { @FastNative private static native void nativeTraceBegin(long tag, String name); @FastNative private static native void nativeTraceEnd(long tag); private Trace() { } ... public static void traceBegin(long traceTag, String methodName) { if (isTagEnabled(traceTag)) { nativeTraceBegin(traceTag, methodName); } } public static void traceEnd(long traceTag) { if (isTagEnabled(traceTag)) { nativeTraceEnd(traceTag); } } ... public static void beginSection(String sectionName) { if (isTagEnabled(TRACE_TAG_APP)) { if (sectionName.length() > MAX_SECTION_NAME_LEN) { throw new IllegalArgumentException("sectionName is too long"); } nativeTraceBegin(TRACE_TAG_APP, sectionName); } } public static void endSection() { if (isTagEnabled(TRACE_TAG_APP)) { nativeTraceEnd(TRACE_TAG_APP); } } }
3.3.3 native layer
In fact, systrace is essentially a package of other tools, including atrace
on the PC side and ftrace
on the device side. ftrace
is the main tracing mechanism in the Linux kernel. . systrace uses atrace
to start tracing, then reads the cache of ftrace
and re-converts it into HTML format
#include<utils/Trace.h> ATRACE_CALL();
The basic analysis methods and principles of systrace are introduced here. More in-depth analysis methods and principles will be updated in subsequent series, so stay tuned.
4. Reference
https://developer.android.com/studio/command-line/systrace
http://gityuan.com/2016/01/17/systrace/
Use Systrace to analyze UI performance – Jianshu