1. Working principle of CPU and GPU

1.1. CPU and GPU architecture

  • CPU: Parse the layout, generate View objects and position properties, and convert them into multi-dimensional vector graphics.

  • GPU: Rasterize vector graphics and draw graphics on the screen.

  • Bridge between CPU and GPU: openGL ES.

1.1.1. Screen display process

Android emits a Vsync signal every 16ms, which acts like a time interrupt. The system refreshes the screen every time it gets a Vsync signal, so it doesn’t feel stuck.

1.1.2. No Vsync

In the second frame of the screen, THE CPU may be busy with other tasks (the main thread is too heavy), so the data is not finished at the end of the second 16ms. Therefore, the GPU can only finish the calculation of the second frame in the third 16ms. At this time, there are two 16ms showing the same picture, and the picture is stuck.

1.1.3. Have Vsync

Every time the Vsync message is sent, the CPU responds to refresh in the first time. At this time, the refresh time of CPU and GPU is consistent with the FPS of the display screen, so there is no lag under normal circumstances.

1.1.4. Drop frames for viewing

2. To be Skipped over. 3. Logcat enter “Skipped” to filter system log, No Filters information, No Verbose level


2. The CPU optimization

In order to reduce the CPU computation of layout resolution in each frame, common methods are nested hierarchical optimization, optimization, optimization, optimization.

2.1. View hierarchy optimization

For complex layouts, try to keep the View hierarchy as flat as possible. The flatter the hierarchy, the less time it takes to complete the layout stage. Google officially recommends no more than 10 layers.

AndroidStudio 2014 Tools 2014 Layout Inspector, select process and Activity, view the Layout tree.

Common base layout comparison

layout performance Nested hierarchy Layout of the difficulty
FrameLayout good low difficult
LinearLayout good high easy
RelativeLayout poor low difficult
ConstraintLayout good low difficult

ConstraintLayout is often used to reduce layout levels and optimize performance.

2.2. The < include / > optimization

Usually you can put a generic Layout into a single Layout file and then use tags to load it in where you need it, such as the navigation bar.

<include
    android:layout_width="match_parent"
    android:layout_height="40dp"
    layout="@layout/titlebar" />
Copy the code

2.3. The < merge / > optimization

Using tags does not directly reduce the level of nesting. If the parent layout of the include is the same as the root layout of the included, and attributes such as background and padding do not need to be set, the layout root tag can be replaced by a tag.


      
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:text="@string/app_name" />

</merge>
Copy the code

Then use tags to load it in where needed.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">// The parent layout of the include will be the parent layout of the merge's child layout<include layout="@layout/merge_view" />
</RelativeLayout>
Copy the code

At this point, you can reduce one layer of layout nesting.

2.4. < ViewStub / > optimization

The same can be used to introduce an external layout. If the imported layout does not display or take up space by default, you can use it instead to save CPU and memory resources when parsing a layout. Such as progress bars, network errors, and other suggestive layouts.

<ViewStub
    android:id="@+id/network_error_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout="@layout/network_error" />
Copy the code

In code, you can find the ViewStub using (ViewStub)findViewById(ID), expand the ViewStub with stub.inflate(), and get the referenced instantiation object.

ViewStub stub = (ViewStub)findViewById(R.id.network_error_layout);
if(stub ! =null) {// Once the ID is inflate once, the ViewStub cannot be found by findViewById
    // After this is saved, you can no longer use this inflate
    networkErrorView = stub.inflate();
}
Copy the code

3. The GPU overdraws

GPU overdrawing is when the same pixel is drawn multiple times in a single frame of screen refresh.

These components are distributed from top to bottom, and the lower levels may be obscured by the higher levels. If you spend time painting the invisible parts, you will overdraw.

By setting the developer option “Debug GPU Overdraw” and displaying the overdraw area, the debugging tool can be opened.

Ideally, white and blue should be drawn only once or twice per pixel, and areas above pink should cover no more than a third of the screen, with no red areas.

3.1 background optimization

Remove the background color of the Activity

  • Set the theme toTheme.TranslucentAnd its sub-themes;
  • Custom themeswindowIsTranslucentfortrue.windowBackgroundTransparent color;

Remove the Layout background color

  • android:background="@null"Or just delete itandroid:backgroundProperties;
  • android:background="@color/transparent", although transparent GPU does not render, but will actually occupy memory, but the color is transparent, not recommended;

Cut out the Canvas

Similar to poker, not all the cards at the bottom are exposed. If you crop the Canvas, you can make the covered part unrendered.

canvas.save();  
canvas.clipRect(left, top, right, bottom);  
// canvas. Other operations ();
canvas.restore();
Copy the code

Reduce transparency

Transparent objects need to draw existing pixels first in order to achieve the correct blending effect. Overdrawing in these cases can be improved by reducing the number of transparent objects to render. For example, to get gray text, you can draw black text in a TextView and set a translucent opacity value for it. However, you can get the same effect by simply drawing text in gray, and with a huge performance boost.


4. GPU presentation mode analysis

The GPU rendering mode analysis tool shows the stages and their relative times in the form of graphs (color-coded histograms).

Set Developer option: GPU/HWUI Presentation mode analysis: Make it appear as a bar chart on the screen, and the debugging tool can be opened.

The bar section Rendering phase instructions
Swap Swap buffer Indicates the amount of time the CPU waits for the GPU to complete its work. If this bar is raised, the application is doing too much work on the GPU.
Issue A command Represents the time it takes Android’s 2D renderer to issue commands to Draw and redraw the display list to OpenGL. The height of this bar is proportional to the sum of the time spent executing each display list. The more lists are displayed, the higher the red bar will be.
Upload Sync and upload Indicates the time taken to upload bitmap information to the GPU. Large segments indicate that the application takes a lot of time to load graphics, loads a lot of small resources or a few large resources.
Draw draw Represents the time used to create and update the view display list. If this part of the bar is high, it indicates that there may be a lot of custom view drawing, or that the onDraw method is doing a lot of work.
Measure Measurement/layout In the view hierarchy [onLayout](Developer.android.com/reference/a…, int, int, int, int)) and [onMeasure](Developer.android.com/reference/a…, int)) the time spent on the callback. Large segments indicate that processing view hierarchies can take a long time, usually due to an excessive number of views that need to be laid out, or other problems arise.
Anim animation Represents the time taken to evaluate all animation programs running this frame. If this section is large, it indicates that your application may be using a custom animator with poor performance, or that updating properties is causing some unexpected work.
Input Input processing Represents the amount of time the application takes to execute the code in the input event callback. If this section is large, the application is spending too much time processing user input. Consider offloading such processing to other threads.
Misc Other time /VSync delay Represents the time taken by the application to perform an operation between two consecutive frames. It may indicate that there is too much processing going on in the interface thread that could have been distributed to other threads.