📜 ⬆️ ⬇️

About the performance of Android applications

Introduction


The first thing I want to say is: the article does not pretend to a very deep level; rather, I want to tell you that performance is not only “faster from NDK to C ++” and “save memory, but garbage collection will often run”, And this is a whole set of measures, because performance problems arise not when a single function works slowly, but in combination.
Did you have the feeling that the application is slowing down, and you no longer know what to do - and the memory does not seem to be eating, and you have already seen the profiler, but there is still no solution. If yes, then these notes are for you.
I will not translate concepts and terms, since I think that almost all developers do not translate them.

Links

(yes, links at the beginning)

Everything that I describe here I learned from:
1. Course on performance from Google (I recommend);
2. developer.android.com (if you didn’t look here, then I have bad news for you).

Overdraw


What is the process of turning your xml markup into what you see on the screen? This is a rather complicated process, but now we are interested in one detail. At one of the stages rasterization occurs. This is the same process when high-level objects like fonts and circles are divided into pixels.

Imagine a simple example:
')
<?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="match_parent" android:background="#ffffff" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> .... </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#000000"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:text="Hello, habrahabr!" /> </LinearLayout> </LinearLayout> 

We have a TextView, which lies in LinearLayout, which also lies in LinearLayout. And each of them has its own background. This means that when TextView will be drawn, it will be drawn on the already drawn LinearLayout, part of which was also drawn on the already drawn. This is called overdraw. Perhaps this in itself is not so critical, but it means that you have problems, for example, with a hierarchy.

In order to find overdraw, you need to tick the Android settings: Settings -> Developer Options -> Debug GPU Overdraw

And your phone will change immediately!

Everything is immediately painted in different beautiful colors:



Blue is all right
Green - 2x overdraw
Light red - 3x overdraw
Red - 4x or more

So, for example, Gmail looks out:



And this is so familiar to many Vivino application:



It is evident who has problems, and who does not.
The first thing you can do to get rid of overdraw is to remove unnecessary background definitions. For example:

 <?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="match_parent" android:orientation="vertical"> <LinearLayout android:background="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"> .... </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:text="Hello, habrahabr!" /> </LinearLayout> </LinearLayout> 

And, you can also write to the Activity:

  @Override public void onCreate(Bundle savedInstanceState) { getWindow().setBackgroundDrawable(null); ... } 

Hierarchy


Building a view tree is a very expensive process. And the general recommendation here is very simple - the simpler, the better. Flat layouts are perfect.

To find trouble spots in your application, you can use the monitor utility, which is included in the Android SDK. There is a kind of " Hierarchy View " in it, and this is what we need.
* How to set up and read details here: http://developer.android.com/training/improving-layouts/optimizing-layout.html
and here: http://developer.android.com/tools/debugging/debugging-ui.html

This utility shows the entire hierarchy of views in the application, and shows how each view is more productive (relative to the others). It looks like this:

image

What do the colored dots show

monitor measures the rendering speed of views for each phase of rendering. Activity:
Left - Draw
Medium - Layout
Right - Measure
As for color, then:
Green means that the view is rendered faster by at least half of the neighboring views.
Yellow means that the view is rendered slower by at least half of the neighboring views.
Red says that everything is bad I twist one of the most time-consuming.

How to interpret these points?

If you have all the red at the "extreme" view (those that are sheets of wood), then they are definitely worth looking at.
If you have a ViewGroup with a large number of children, and they have a dot showing measure red, then you should definitely look at the hierarchy.

In our example, it could be made flat quite easily:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/my_layout" android:background="#ffffff" android:layout_width="wrap_content" android:layout_height="wrap_content"> .... </LinearLayout> <TextView android:layout_below="@+id/my_layout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ff0000" android:text="Hello, habrahabr!" /> </RelativeLayout> 


Viewstub


ViewStub is a view that is a simple container and can contain only one child:

 <ViewStub android:id="@+id/stub" android:inflatedId="@+id/subTree" android:layout="@layout/mySubTree" android:layout_width="120dip" android:layout_height="40dip" /> 

But the whole thing is that the layout, which is contained in the ViewStub, will be created only if the ViewStub is visible , or if it has directly called the inflate () method .

Learn more: http://developer.android.com/reference/android/view/ViewStub.html

This can and should be used if your part of the markup becomes visible only in some cases or by pressing a button. That is, it is something like a lazy initialization.

Write quick applications, colleagues.

Source: https://habr.com/ru/post/255997/


All Articles