Android performance optimization, android

Source: Internet
Author: User

Android performance optimization, android

This chapter describes the performance of android advanced development. It mainly includes three performance knowledge points: power, view, and memory.

1. View performance (1) Overview of Overdraw

Overdraw refers to over-drawing. It refers to the fact that a pixel is drawn multiple times within a frame (16.67 ms). In theory, it is optimal to draw a pixel only once at a time, however, due to the overlapping layout, some pixels will be drawn multiple times, and each painting will correspond to a set of drawing commands on the CPU and some operations on the GPU, when this operation takes more than 16.67ms, frames are dropped, which means the application is stuck. Therefore, repeated painting of overlapping invisible elements will incur additional overhead, overdraw should be minimized.

(2) Overdraw Detection

Android provides the Overdraw measurement option. In the developer option-Debug GPU Overdraw (Show GPU Overdraw), open the option to view the Overdraw status of the current page, you can observe the drawing status of the screen. The tool uses three different colors to draw a screen to indicate where overdraw occurs and to what extent:

  • No color: No overdraw. Pixels are painted only once.
  • Blue: indicates that overdraw is doubled. Pixels are drawn twice. The blue of a large film is acceptable (if the entire window is blue, you can get rid of one layer ).
  • Green: indicates that overdraw is twice as green. Pixels are drawn three times. Moderate green areas are acceptable, but you should try to optimize and reduce them.
  • Light red: It means three times overdraw. Pixels are drawn four times, which is acceptable in a small range.
  • Dark red: 4 times overdraw. Pixels are drawn five or more times. This is incorrect and you need to fix it.

To improve the program's View performance, the general principle is to avoid overlapping and invisible elements.

(3) Overdraw Improvement 1) Properly Select the control container

The Layout controls provided by Android mainly include LinearLayout, TableLayout, FrameLayout, and RelativeLayout. The same interface can be expressed using different container controls, but the complexity of each container control's description interface is different. Generally, LinearLayout is the easiest and RelativeLayout is more complex. LinearLayout can only be used to describe controls that are arranged consecutively in one direction, while RelativeLayout can be used to describe interfaces with any complexity .. To sum up, LinearLayout is easy to use, efficient, and expressive. RelativeLayout is complex, with strong expressiveness and low efficiency. From the perspective of overdraw reduction, LinearLayout will increase the level of the number of controls. Naturally, RelativeLayout is better, however, when using LinearLayout on a certain interface does not bring more control numbers and control levels than RelativeLayout, LinearLayout is the first choice.

2) Remove the Default background of the window.

When you use themes that come with Android, windows will be added with a solid background by default, which is held by DecorView. When a background image or background color is added to the custom layout, the background of the DecorView is useless, but it will generate an Overdraw, resulting in performance loss. You can call getWindow (). setBackgroundDrawable (null) after setContentView () in onCreate (), or add android: windowbackground = "null" in theme ".

3) Remove unnecessary background

If the parent container already has a background, do not set the background corresponding to the Child control or a large layout background. Avoid setting a local duplicate background.

4) custom View processing

For custom view views, you can use canvas. clipRect () to help the system identify visible areas. This method can specify a rectangular area, which is drawn only in this area, and other areas will be ignored. This API can help custom views with multiple groups of overlapping components to control the display area. At the same time, the clipRect method can also help to save CPU and GPU resources. Drawing commands outside the clipRect area will not be executed, and those components whose content is in the rectangle area will still be drawn. In addition to the clipRect method, we can also use canvas. quickreject () to determine whether it is not intersecting with a rectangle, thus skipping the painting operations in non-rectangular areas.

5) Efficient placeholder ViewStub

In this case, the runtime dynamically determines the View or layout based on the conditions. A common practice is to write all views on it. First, set their visibility to View. GONE, and then dynamically change its visibility in the code. The disadvantage of this mode is resource consumption. Although the initial View of the View. GONE is still Inflate in the Inflate layout. When the program runs, it creates an object and is instantiated. It is set to properties and consumes memory and other resources.

We recommend that you use android. view. ViewStub. ViewStub is a lightweight View that is invisible and occupies very small resources. You can specify a layout for ViewStub. In the Inflate layout, only ViewStub will be initialized. Then, when ViewStub is set to visible, or ViewStub is called. when inflate () is used, the layout directed by ViewStub will be Inflate and instantiated, and the layout attribute of ViewStub will be transmitted to the layout pointed to by it. In this way, ViewStub can be used to conveniently display a layout during running.

6) make good use of draw9patch

Add a border to the ImageView. Generally, a background image is set after the ImageView to solve the problem perfectly when the border is exposed. At this time, the ImageView is set with two layers of drawable, two layers of drawable overlap areas are drawn twice, resulting in overdraw. Optimization solution: make the background drawable into a draw9patch, and set the overlapping parts with the foreground to transparent. Because the Android 2D Renderer optimizes the transparent area in draw9patch, this overdraw is optimized.

7) Merge

Use the Merge label as the Container Control. The first seed view does not need to specify any layout attribute for the parent view. That is to say, the parent container is only a container, and the Child view only needs to be directly added to the parent view for display. In addition, if a layout (or view) needs to be embedded in LinearLayout, and the root node of the layout (or view) is also LinearLayout, a layer of unused Nesting is added, undoubtedly, this will only slow down the program speed. At this time, if we use the merge root tag, we can avoid that problem.

2. memory performance (1) memory allocation and recovery

The Dalvik Heap of each process reflects the memory usage range. This is the Dalvik Heap Size mentioned in the logic sense. It can grow as needed, but a system will set an upper limit for the Growth Behavior.

Logically speaking, the Heap Size and the physical memory Size are not equal. Proportional Set Size (PSS) records the memory occupied by the application and shared with other processes.

The Android system does not fragment the idle memory areas in Heap. The system will only determine whether Heap's tail end space is sufficient before the new memory allocation. If the space is insufficient, GC operations will be triggered to create more idle memory space. In the Android advanced system version, there is a Generational Heap Memory model for the Heap space. recently allocated objects are stored in the Young Generation area. When this object stays in this region for a certain amount of time, it will be moved to the Old Generation, and then accumulated for a certain amount of time to move to the Permanent Generation region. The system performs different GC operations based on different memory data types in the memory. For example, objects allocated to the Young Generation area are usually more easily destroyed and recycled, at the same time, the GC operation speed in the Young Generation region is faster than that in the Old Generation Region (1 ).

 

Figure 1 perform different GC operations based on different Memory Data Types

The memory area of each Generation has a fixed size. As new objects are gradually allocated to this area, GC operations are triggered when the total size of objects approaches the threshold value of this level of memory area, to free up space for storing other new objects (2 ).

 

Figure 2 GC operation triggered by object value approaching Threshold Value

Generally, when GC occurs, all threads are paused. The time used for GC execution is also related to the Generation in which the GC occurs. The GC operation time in Young Generation is the shortest, the Old Generation is the second, and the Permanent Generation is the longest. The execution duration is also related to the number of objects in the current Generation. traversing the tree structure to find 20000 objects is much slower than traversing 50 objects.

(2) memory test plug-in 1) LeakCanary Introduction

LeakCanary is a tool used to detect memory leaks. It can be used for Java and Android and is contributed by Square, a famous open-source organization.

2) How LeakCanary works
  • RefWatcher. watch () creates a KeyedWeakReference object for North monitoring.
  • Next, check whether the reference is cleared in the background thread. If not, GC is triggered.
  • If the reference is still not cleared, dump heap memory to A. hprof file and store it in the mobile phone system.
  • HeapAnalyzerService is started in another independent process. HeapAnalyzer is used to parse heap memory through HAHA.
  • HeapAnalyzer calculates the shortest and strong reference path of GC ROOTs to determine whether Leak occurs, and then establishes a reference chain that causes leakage. The result is returned to the DisplayLeakService of the application process, and a notification of leakage is displayed.
(3) memory optimization 1) use large heap with caution

Android devices have different memory sizes based on differences in hardware and software settings. They set different Heap limits for applications. You can call getMemoryClass () to obtain the available Heap size of the application. In some special scenarios, you can declare a larger heap space for the application by adding the largeHeap = true attribute under the application tag of manifest. Then, you can use getLargeMemoryClass () to obtain the larger heap size threshold.

However, the purpose of declaring a larger Heap threshold is to consume a large amount of RAM applications (such as a large image editing application ). Do not request a large Heap Size easily because you need to use more memory. Large heap is used only when you know exactly where a large amount of memory will be used and you know why the memory must be retained. Therefore, use the large heap attribute with caution. The use of additional memory space will affect the overall user experience of the system and lead to a longer running time for each gc.

2) Design a suitable cache Size Based on the device memory threshold and other factors

For example, when designing the Bitmap LRU cache for ListView or GridView, consider the following points:

  • How much memory space does the application have?
  • How many images are displayed on the screen at a time? How many images need to be cached in advance so that they can be immediately displayed on the screen when sliding fast?
  • What is the screen size and density of a device? An xhdpi device requires a larger Cache than hdpi to hold the same number of images.
  • What are the sizes and configurations of different pages for Bitmap design, and how much memory will be consumed?
  • How often are page images accessed? Do some of these images have higher access frequency than other images? If yes, you may want to save those most frequently accessed to the memory, or set multiple LruCache containers for bitmaps of different groups (grouped by Access Frequency.
3) Select a suitable folder for storing resource files.

Images in different dpi folders, such as hdpi, xhdpi, and xxhdpi, are processed by scale on different devices. For example, if we only put a 100100 image under the hdpi directory, then according to the conversion relationship, the mobile phone of xxhdpi will reference the image to be stretched to 200200. Note that in this case, the memory usage will be significantly improved. For images that do not want to be stretched, you need to put them in the assets or nodpi directory.

4) Try catch some large Memory Allocation Operations

In some cases, we need to evaluate the codes that may occur with OOM in advance. For these codes that may occur with OOM, add the catch mechanism, you can try a degraded memory allocation operation in catch. For example, if you catch OOM in decode bitmap, you can try to double the sampling ratio and try decode again.

5) exercise caution when using static objects

Because the lifecycle of static objects is too long, it is consistent with that of the application process. improper use may lead to object leakage. In Android, exercise caution when using static objects.

6) Pay special attention to the unreasonable possession of the singleton object.

Although the singleton mode is simple and practical, it provides a lot of convenience, but because the life cycle of the Singleton is consistent with that of the application, the leakage of the holding object is very likely to occur if the use is unreasonable.

7) cherish Services resources

The application must use the service in the background. Unless it is triggered and executes a task, the Service should be stopped at other times. In addition, pay attention to the memory leakage caused by the failure to stop the service after the service completes the task. When you start a Service, the system tends to keep the process where the Service is located to keep the Service. This makes the process run very expensive because the system cannot free up the RAM space occupied by the Service to other components. In addition, the Service cannot be Paged out. This reduces the number of processes that the system can store in the LRU cache. It affects the switching efficiency between applications and may even cause unstable system memory usage, as a result, you cannot continue to maintain all the currently running services. We recommend that you use IntentService, which will end yourself as soon as possible after processing the tasks assigned to it.

8) Use ProGuard to remove unnecessary code

ProGuard can compress the code by removing unnecessary code, renaming classes, domains and methods, and optimize and confuse the code. Using ProGuard can make your code more compact and reduce the memory space required by mapping code.

9) use a more lightweight Data Structure

Consider using traditional data structures such as ArrayMap/SparseArray instead of HashMap.

Compared with the ArrayMap container specially compiled by Android for the mobile operating system, HashMap containers usually show low efficiency and occupy more memory. Generally, the implementation of HashMap consumes more memory because it requires an additional instance object to record Mapping operations. In addition, SparseArray is more efficient because it avoids autoboxing of keys and values and avoids unboxing after packing.

10) Avoid using Enum in Android

The official Android training course mentioned "Enums often require more than twice as much memory as static constants. you shoshould strictly avoid using enums on Android. ", for detailed principles, see" Android performance optimization model (iii) ", so avoid using enumeration in Android.

11) Reduce the memory usage of Bitmap objects

Bitmap is a fat man who is very easy to consume memory. Reducing the memory usage of the created Bitmap is a top priority. Generally, there are two measures as follows:

  • InSampleSize: scaling ratio. Before loading an image into the memory, we need to calculate an appropriate scaling ratio to avoid unnecessary large image loading.
  • Decode format: Decoding format. Select ARGB_8888/RBG_565/ARGB_4444/ALPHA_8.
12) use smaller images

When it comes to resource images, we need to pay special attention to whether there is space to compress this image and whether it can use smaller images. Using smaller images as much as possible can not only reduce memory usage, but also avoid a large number of inflationexceptions. If a large image is directly referenced by an XML file, InflationException may occur due to insufficient memory during view initialization. The root cause of this problem is OOM.

13) Reuse of memory objects

Most of the reuse of objects, the final implementation scheme is to use the object pool technology, or explicitly create an object pool in the program during code writing, and then process the reuse implementation logic. Either it is to use some of the existing reuse features of the system framework to reduce repeated object creation, thus reducing memory allocation and recovery.

14) Reuse the resources provided by the system

The Android system has many built-in resources, such as strings, colors, images, animations, styles, and simple la S. These resources can be directly referenced in applications. This not only reduces the workload of applications and the size of APK, but also reduces the memory overhead to a certain extent and improves reusability. However, it is also necessary to pay attention to the version differences of the Android system. for situations where the performance of different system versions is very different and does not meet the requirements, the application must be built in.

15) check whether the Cursor object is closed in time

In the program, we often perform database query operations, but there are often situations where the Cursor is not closed in time due to carelessness. The leakage of these Cursor results in a significant negative impact on memory management if it appears multiple times. We need to remember to close the Cursor object in time.

16) AvoidOnDrawMethod to create the execution object

For methods that are frequently called like onDraw, do not create an object here because it will quickly increase memory usage and cause frequent gc, memory jitter.

17)StringBuilder

In some cases, a large number of String concatenation operations are required in the Code. In this case, it is necessary to consider using StringBuilder to replace frequent "+ ".

18) Pay attention to Activity Leakage

Generally, Activity leakage is the most serious problem in Memory leakage. It occupies a large amount of memory and has a wide impact. Pay special attention to the Activity leakage caused by the following two situations:

  • Internal class reference causes Activity Leakage

The most typical scenario is the Activity leakage caused by Handler. If there are delayed tasks in Handler or the queue of tasks waiting for execution is too long, the Activity leakage may occur due to the continued execution of Handler. In this case, the reference link is Logoff-> MessageQueue-> Message-> Handler-> Activity. To solve this problem, you can execute remove the message and runnable object in the Handler message queue before the UI exits. Or use Static + WeakReference to disconnect the reference relationship between Handler and Activity.

  • The Activity Context is passed to other instances, which may cause leakage when it is referenced.

Leakage caused by internal classes will not only occur on the Activity, but should be paid special attention to any other internal classes! Consider using static internal classes as much as possible, and using the WeakReference mechanism to avoid leakage due to mutual reference.

19) Consider using Application Context instead of Activity Context.

For most cases where the Activity Context is not required (the Dialog Context must be the Activity Context), you can consider using the Application Context instead of the Activity Context to avoid accidental Activity leakage.

(3) Power Optimization

Power is actually one of the most valuable resources for handheld devices. Most devices need to be constantly charged to continue using them. Unfortunately, for developers, power optimization is the last thing they will consider. However, it is certain that your application cannot be the largest power-consuming user.

The following measures can significantly reduce power consumption:

  • We should minimize the number and duration of screen wakeup. We should use WakeLock to handle the wake-up problem, correctly perform the wake-up operation, and close the operation in time to enter the sleep state.
  • Some operations that do not have to be performed immediately, such as uploading songs and image processing, can be performed only when the device is in the charging status or when the power is sufficient.
  • The operation that triggers network requests keeps wireless signals for a period of time. We can package scattered network requests for one operation to avoid excessive power consumption caused by wireless signals. The power consumption of wireless signals caused by network requests.
1) several main causes and functions of Power Consumption
  • Network Transmission of large data volumes (network)
  • Non-stop network switching (network)
  • Parse a large amount of data (CPU)
2) Network Optimization
  • Check the network connection before network requests. No network connection, no request
  • Determine the network type and request specific data under a specific network. For example, when a large amount of data is transmitted, requests are sent under wifi. Download data only consumes 1/3 of the power of 2, 3, and 4G in wifi.
  • Use efficient parsing tools. Select an appropriate resolution tool based on the data volume of your business. For example, json is generally recommended for protocol parsing on android.
  • Using GZIP compression to download data can reduce network traffic and shorten the download time.
  • Use cache properly to avoid repeated operations
  • Use push instead of loop requests
  • The operation that triggers network requests keeps wireless signals for a period of time. We can package scattered network requests for one operation to avoid excessive power consumption caused by wireless signals.
  • Is what JobScheduler API does. It combines the desired wake-up time based on the current situation and task, for example, when the instance is being charged or connected to WiFi, or when the task is executed together. We can use this API to implement many free scheduling algorithms.
3) Power Optimization Strategy
  • Check whether all the wake-up locks are redundant or useless.
  • Centralized and unified transmission of related data requests; streamlined data to reduce the transmission of useless data.
  • For more information, see JobScheduler.
  • Streamline redundant services to avoid long-time power consumption.
  • Pay attention to the location information acquisition, and close it in time after use.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.