Android performance optimization – Caton and layout optimization

Time:2022-1-25
  • Layout can be said to be the most important item of the app. Users have strong perception. No matter how your code is written, users don’t know. Users can only see and operate the app. A more beautiful and reasonable layout and smoother experience are good apps.
  • For example, when operating wechat cards, users will only feel that the mobile phone is not working, not wechat. However, for other app cards, users feel that the app is not working, not the mobile phone. ┓( ´∀` )┏
  • Android performance optimization – startup speed optimizationYou can also study together.

1. Caton analysis

1.1 refresh rate

  • The main root cause of performance problems such as Caton perceived by most users is rendering performance. From the perspective of designers, they hope that the app can have more animation, pictures and other fashion elements to achieve a smooth user experience. However, Android system may not be able to complete those complex interface rendering operations in time. The Android system sends a Vsync signal every 16ms to trigger the rendering of the UI. If each rendering is successful, the 60fps required for a smooth picture can be achieved. In order to achieve 60fps, it means that most operations of the program must be completed within 16ms.
  • In the above paragraph, the app is becoming more and more cool. There are a lot of animations and videos. Video advertisements should be displayed when it is started. These are no pressure for the flagship Android machine, but for the old mobile phone or entry-level mobile phone, complex pages have a large amount of calculation, and the CPU and GPU can’t process them, so they can’t be displayed smoothly.

16ms refresh
  • If your operation takes 24ms, the system cannot render normally when it gets the Vsync signal, which leads to frame loss. Then the user will see the same frame within 32ms.

24ms refresh

1.2 PerfDog

Tencent perfdog, performance monitoring

  • In the following figure, in perfdog, use Huawei p30pro to check the refresh of microblog. When the static microblog content is not sliding, the refresh rate is 0fps. When sliding quickly, the refresh rate is about 60fps. You can also check the CPU and memory usage.

micro-blog
  • As shown in the figure below, when the video is played on Weibo, the refresh rate has always been about 60fps.

Microblog video
  • As shown in the figure below, ordinary apps can basically reach 60fps, but the camera is not. The camera takes pictures stably at 30fps. When taking selfie, the beauty is turned on and reduced to 24fps. It seems that the beauty of camera and AI is better.
  • Small knowledge, movies or videos viewed online are usually played at the speed of 24 frames / second, which can save performance and have a good effect. Sony a7m3 camera can record 120 frames of slow motion, which can be upgraded by 4 or 5 times.

camera

1.3 CPU Profile

2. Layout optimization

2.1 over drawing

  • Overdraw describes how a pixel on the screen is drawn multiple times in the same frame. In the multi-level UI structure, if the invisible UI is also drawing, some pixel areas will be drawn many times. This wastes a lot of CPU and GPU resources.
  • Blue and green are better. Red means there are more levels. In order to achieve a good-looking effect, a multi-layer layout will be set. Excessive drawing consumes more performance, and the entry-level machine will get stuck.

Over draw
  • The mobile phone enters the developer option, debugs GPU over drawing, and opens the display over drawing area.
  • The layout of shell app is mostly blue and green, which shows that there is no over drawing of their app, which is very good.

shell
  • There will be over drawing in the following list, but the area is small, only the part of the content.

Insert picture description here
  • Developers can choose to display the layout boundary. You can see that the layout level of the shell is really small, and it is very clear and neat.

shell
  • The over drawing area of Weibo app basically covers the whole screen. In addition to Weibo, wechat, Taobao and other list apps, most of them are also red. The reason may be that list apps, in addition to the parent layout, also need a recyclerview and ItemView, which can not avoid over drawing; But if the whole item is over drawn, the shell will be better.

micro-blog
  • The layout of Weibo will look more complicated.

Insert picture description here

2.2 solving over drawing

  • 1. Compared with the above microblog and shell, the microblog item is over drawn. When we write recyclerview, if only one of the parent layout, recyclerview and item background of recyclerview is set, it will not be rendered without setting the background, otherwise it will be over drawn.
  • 2. The parent layout and the child layout should also set only one background as far as possible, unless there is no way to need the background.
  • 3. Generally, the child view will overwrite the parent view after drawing, so the background is generally set in the child view.
  • 4. The hierarchy of the view can be reduced if it can be reduced. The more levels, the slower the drawing speed.
  • 5. Set the transparency of the view as little as possible. If a view has alpha set, it needs to know what the following view is, and then draw itself, which is over drawing. If the text has transparency, it can be set in the color number.

2.3 level optimization

  • Android studio has layout level tools,Layout Inspector, after running the app, you can see the hierarchy of each page. If there are too many levels, it will definitely cause jamming and slow startup. It is said in startup optimization,

  • The specific contents of the layout tree can be seen on the left.

    Layout tree
  • Like Scrollview, only one ViewGroup can be placed in it, which is irreducible, butLinearLayout set of LinearLayoutYes, it can be passedConstraintLayoutTo solve the problem, constrained layout can be said to combine the advantages of linear layout and relative layout, which can effectively reduce the level.

view tree

2.4 using merge

  • We have some layouts that can be used in general to avoid repeated codeinclude
  • However, if you useinclude, but the layout inside is another oneViewGroupIf so, there will be too many levels, which can be used at this timemergeThe child views in the tag will be arranged according to the ViewGroup in the external include, so as to reduce the level.
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <include layout="@layout/layout_head" />
</LinearLayout>

<!--  layout_head -->
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_head"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="text1"
        android:textSize="16sp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="text2"
        android:textSize="16sp" />
</merge>

Copy code
  • You can see the use ofmergeThe view inside is directly in the LinearLayout level.

2.5 ViewStub

  • We sometimes draw the layout according to the needs, and thenandroid:visibilitySet as“invisible”Or“gone”invisibleandgoneAlthough invisible, they still have initialization, which takes up memory and resources. The former also takes up location.
  • We can useViewStubTo wrap these views that need to be hidden and displayed. It is a lightweight view. It is invisible and does not occupy resources. Only when setinflateThe display is initialized only when.
<ViewStub
    android:id="@+id/viewStub_title"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout="@layout/layout_title"
    app:layout_constraintTop_toTopOf="parent" />

<!-- layout_title -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:orientation="horizontal">

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:id="@+id/image_back"
        android:padding="12dp"
        android:src="@drawable/ic_back" />

    <TextView
        android:layout_width="0dp"
        android:id="@+id/tv_title"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center"
        android:text="title" />
</LinearLayout>
Copy code
  • In activityviewStub.inflate()Can be displayed, but cannot be called repeatedlyinflate(); Otherwise, an exception is reported:

java.lang.NullPointerException: Attempt to invoke virtual method ‘android.view.View android.view.ViewStub.inflate()’ on a null object reference。

viewStub = findViewById(R.id.viewStub_title);
viewStub.inflate();
//After that, you can initialize the view inside
ImageView ivBack = findViewById(R.id.image_back);
ivBack.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        finish();
    }
});
TextView tvTitle = findViewById(R.id.tv_title);
Copy code

3. Other optimization

3.1 do not create objects in OnDraw

  • We often need to customize the viewonDraw()Do not create objects in the method, because custom view drawing will be called very frequentlyonDraw, although the objects in the method are recycled after they are created, frequent creation and destruction of objects will lead toMemory jitter and GC, andGCMore will get stuck.

Avoid creating objects in OnDraw

3.2 asynchronous loading layout

Google asynclayoutfilter Library

  • During the process of loading the XML layout, the layouteinflator will use IO to read the XML layout file for XML parsing in the main thread, and then use reflection to create the view / ViewGroup object in the layout according to the parsing result. As the complexity of the layout increases, the time-consuming process will naturally increase. Android provides us withAsynclayoutinflaterComplete the time-consuming loading operation in the asynchronous thread, and finally call back the loading result to the main thread.
  • AsynclayoutinflaterNote:
  • 1. If asynchronous inflate is used, the generatelayoutparameters function of the parent of this layout is thread safe.
  • 2. All built views must not create a handler or call looper myLooper; (because it is loaded in an asynchronous thread, the asynchronous thread does not call looper.prepare by default).
  • 3. Asynclayoutinflator does not support setting layoutinflator Factory or layoutinflator Factory2;。
  • 4. Loading layouts containing fragments is not supported.
  • 5. If asynclayoutinflator fails, it will automatically fall back to the UI thread to load the layout.

In the open source project:https://github.com/Android-Alvin/Android-LearningNotesIt has been included in, including self-study programming routes in different directions, interview questions collection / face experience, and a series of technical articles. The resources are constantly updated

Recommended Today

Building the basic static page of Vue chat room

design sketch HTML: <template>     <view>         <view>             <scroll-view scroll-y=”true”>                 <div> <!– Message notification — >                     <div>                         <div>2021-12-28 16:50:00</div> < div > XXX processed this work order < / div >                     </div> <!– Left — >                     <!– <div></div> –> <!– Right — >                     <!– <div></div> –>               </div>               <div>                 <div>                     <image src=”../../static/logo.png”>                     <div>                         <div>2021-12-28 16:50:00</div> < […]