Android App performance optimization analysis

This paper makes a detailed analysis on the four aspects of Android App performance optimization, and explains the principle and key points in detail. The following is the whole content:

When it comes to Android phones, most people's impression is that they become a little stuck after a period of time. Some programs crash inexplicably during operation. Open the system folder and find many more files. Then use the mobile housekeeper app to constantly clean and optimize, so they feel that the running speed has been slightly improved, Even if the mobile phone scores far ahead in front of various performance scoring software, it still feels that no matter how much memory space there is, it is far from enough. I believe that every user using the Android system has had the above similar experience. Indeed, the Android system is not as fluent as the IOS system. Why? Clearly, when looking at the hardware configuration of the mobile phone, the Android device will not be inferior to the IOS device, or even stronger than it. The key lies in the software. There are many reasons for this phenomenon, which are listed as follows:

In fact, in recent years, with the continuous iteration of Android version, the Android system provided by Google has become more and more smooth. At present, the latest released version is Android 8.0 Oreo. However, the Android mobile phone system used by most users in China is the version customized by major manufacturers, which is often not the latest native system kernel. Most of them may still stay on Android 5.0 System, and even the proportion above Android 6.0 is still small, so the update is delayed. Since the Android system source code is open, everyone can modify the source code as long as they comply with the corresponding agreement. Then domestic manufacturers will transform the Android source code into their own external release systems, such as the familiar Xiaomi mobile phone MIUI system, Huawei mobile phone emui system, oppo mobile phone coloros system, etc. Since each manufacturer has modified the Android native system source code, there will be a problem, that is, the famous Android fragmentation problem. The essence is that the application compatibility of different Android systems is different and can not reach consistency. Due to various Android fragmentation and compatibility problems, Android developers need to adapt different systems when developing applications. At the same time, the development level of each Android Developer is uneven, and there are different types of problems in the written application performance, resulting in different user experience during use, Then some problem users will turn into Android system problems, which will affect the evaluation of Android phones. performance optimization

Today, I want to focus on the performance optimization of android app, that is, what should be paid attention to when developing applications and how to better improve the user experience. In addition to attractive functions and interactions, a good application should also have high requirements for performance. Instant applications are very characteristic and may attract some users in the early stage of the product, but if the user experience is not good, it will also bring a bad reputation to the product. So how should a good application be defined? It mainly includes the following three aspects:

Business / functional logical interaction excellent performance

As we all know, Android system, as an operating system mainly based on mobile devices, has certain restrictions on hardware configuration. Although the configuration is now more and more advanced, it is still unable to compare with PC. when it uses unreasonable CPU and memory or consumes too much resources, it will encounter stability problems caused by insufficient memory and Caton problems caused by too much CPU consumption.

When faced with problems, people think of contacting users and then viewing logs, but they don't know the feedback on performance problems. The reasons are also very difficult to find. Most logs are of little use. Why? Because most of the performance problems are non essential problems, the problem location is difficult to reproduce, and there is no key log, of course, the reason can not be found. These problems greatly affect the user experience and function use, so it is very important to understand some solutions for performance optimization, and optimize our application in the actual project, so as to improve the user experience.

Four aspects

The performance problems of user experience can be summarized into four categories:

Smooth and stable, power and flow saving, small installation package

The main causes of performance problems are the same and different, but in the final analysis, they are nothing more than memory usage, code efficiency, appropriate policy logic, code quality and installation package volume. They are sorted and classified as follows:

As can be seen from the figure, building a high-quality application should aim at four directions: fast, stable, economical and small.

Fast: avoid jamming during use, fast response, reduce user waiting time and meet user expectations.

Stable: reduce the crash rate and anr rate, and do not crash and respond during user use.

Save: save traffic and power consumption, reduce user use cost, and avoid hot mobile phone when using.

Small: the installation package is small, which can reduce the installation cost of users.

In order to achieve these four goals, the specific implementation is the problems in the right frame: Caton, unreasonable memory use, poor code quality, disordered code logic and too large installation package. These problems are also the most encountered problems in the development process. While realizing the business requirements, we also need to take this into account and spend more time thinking about how to avoid optimization after the functions are completed, Otherwise, the maintenance cost will increase after the implementation of functions such as.

Caton optimization

Android applications start slowly and often get stuck when used, which greatly affects the user experience and should be avoided as much as possible. There are many scenarios in Caton, which can be divided into four categories: UI drawing, application startup, page Jump and event response, as shown in the figure:

The root causes of these four Caton scenarios can be divided into two categories:

Interface drawing. The main reason is that the drawing level is deep, the page is complex, and the refresh is unreasonable. These reasons lead to more Caton scenes in the UI, the initial interface after startup, and jump to the drawing of the page. Data processing. The reason for this stuck scenario is that the amount of data processing is too large. It is generally divided into three situations: one is that the data is processing the UI thread; the other is that the data processing occupies a high CPU, resulting in the main thread unable to get the time slice; the third is that the increase of memory leads to frequent GC, resulting in stuck.

There are many reasons for Caton, but no matter what the reasons and scenarios are, they are finally displayed on the device screen to reach the user. In the final analysis, there is a problem with the display. Therefore, to solve Caton, we must first understand the display principle of Android system.

Display principle of Android system

The Android display process can be summarized as follows: the Android application caches the measured, laid out and drawn surface data, renders the data to the display screen through the surfaceflinger, and refreshes the data through the Android refresh mechanism. In other words, the application layer is responsible for rendering, and the system layer is responsible for rendering. The data to be drawn by the application layer is transmitted to the system layer service through inter process communication, and the system layer service updates the data to the screen through the refresh mechanism.

We all know that there are three core steps in each view drawing of Android: measure, layout and draw. The specific implementation starts from the performtraversals () method of the viewrootimp class. Both measure and layout obtain the size and position of the view through recursion, and take the depth as the priority. It can be seen that the deeper the level, the more elements and the longer the time-consuming.

The real rendering of the data to be displayed on the screen is realized through the surfaceflinger service in the system level process. What is the main work of this surfaceflinger service? As follows:

In response to client events, create a layer and establish a connection with the client's surface. Receive client data and attributes, and modify layer attributes, such as size, color, transparency, etc. Refresh the created layer content to the screen. Maintain the sequence of layers and make clipping calculation for the final output of layers.

Since there are two different processes, a cross process communication mechanism must be needed to realize data transmission. In the Android display system, Android anonymous shared memory: sharedclient is used. A sharedclient will be created between each application and surfaceflinger, and then up to 31 sharedbufferstack can be created in each sharedclient, Each surface corresponds to a sharedbufferstack, that is, a window.

A sharedclient corresponds to an Android application, and an Android application may contain multiple windows, that is, surface. In other words, sharedclient contains a collection of sharedbufferstack, in which double buffering and triple buffering technologies are used in the display refresh mechanism. Finally, to sum up, the overall display process is divided into three modules: the application layer is drawn to the cache, and the surfaceflinger renders the cache data to the screen. Because it is a different process, it uses Android's anonymous shared memory sharedclient to cache the data to be displayed to achieve the goal.

In addition, we also need a noun: FPS. FPS represents the number of frames delivered per second. Ideally, 60 FPS will not feel the card, which means that each drawing time should be less than 16 Ms. However, Android system may not be able to complete those complex page 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. If an operation takes 24ms, the system cannot render normally when it gets the Vsync signal, so frame loss occurs. Then the user will see the same frame within 32ms. This phenomenon is common when executing animation or sliding list. It may also be that your layout is too complex and too many drawing units are stacked, so you can't finish rendering in 16ms, resulting in untimely refresh.

Caton root cause

According to the display principle of Android system, the root causes affecting rendering are as follows:

The drawing task is too heavy and it takes too long to draw the content of a frame. The main thread is too busy. According to the Vsync signal transmitted by the system, the data is not ready, resulting in frame loss.

Drawing takes too long. There are some tools that can help us locate the problem. If the main thread is too busy, you should pay attention. The key responsibility of the main thread is to handle user interaction, draw pixels on the screen, load and display relevant data. Therefore, it is particularly necessary to avoid any main thread, so that the application can maintain an immediate response to user operations. To sum up, the main thread mainly does the following work:

UI lifecycle control system event processing message processing interface layout interface drawing interface refresh

In addition, we should try to avoid putting other processing in the main thread, especially complex data calculation and network request.

Performance analysis tools

Performance problems are not easy to reproduce or locate, but they still need to be solved when they really encounter problems. Therefore, to analyze the problems and confirm whether the problems are solved, we need to use corresponding debugging tools, such as the hierarchy view at the layout level, the GPU profile tool and the static code inspection tool lint on the Android system, These tools play a very important role in performance optimization, so you should be familiar with them and know what tools to analyze in what scenarios.

1,Profile GPU Rendering

In the mobile developer mode, there is a Caton detection tool called profile GPU rendering, as shown in the figure:

Its functional features are as follows:

A graphics monitoring tool can reflect the current drawing time in real time. The horizontal axis represents the time, and the vertical axis represents the time of each frame. With the passage of time, the refresh and presentation from left to right provides a standard time. If it is higher than the standard time, it means that the current frame is lost

2,TraceView

Traceview is a built-in tool of the Android SDK. It is used to analyze the function call process and analyze the performance of Android applications and framework layer code. It is a graphical tool, which will eventually generate a chart to explain the performance analysis. It can analyze the execution time of each method, in which the parameter dimensions such as the number of calls, recursion times and actual time can be counted. It is very intuitive and convenient to analyze the performance.

3. Systrace UI performance analysis

Systrace is a performance data sampling and analysis tool provided by Android 4.1 and above. It returns some information from the perspective of the system. It can help developers collect the operation information of key Android subsystems, such as surface linker, windowmanagerservice and other key modules, services and view systems of the framework, so as to help developers more intuitively analyze system bottlenecks and improve performance. Systrace's functions include tracking the system's I / O operation, kernel work queue, CPU load, etc. it provides good data for UI display performance analysis, especially for problems such as poor animation playback, rendering card, etc.

Optimization suggestions

1. Layout optimization

Whether the layout is reasonable or not mainly affects the page measurement time. We know that the display measurement and drawing process of a page are completed through recursion. The traversal time of the multi tree is related to the height h of the tree, and its time complexity is O (H). If the level is too deep, each additional layer will increase the page display time, Therefore, the rationality of the layout is very important.

What are the methods of layout optimization, mainly through reducing levels, reducing measurement and drawing time, and improving reusability. The summary is as follows:

Reduce levels. Reasonably use relativelayout and linerlayout, and reasonably use merge. Increase display speed. Using viewstub, it is an invisible view object that does not occupy the layout position and occupies very small resources. Layout reuse. Reuse can be improved by labeling. Use wrap as little as possible_ content。 wrap_ Content will increase the calculation cost of layout measure. When the width and height are known to be fixed, wrap is not needed_ content 。 Delete useless properties in the control.

2. Avoid over drawing

Over drawing means that a pixel on the screen is drawn multiple times in the same frame. In the multi-level overlapping UI structure, if the invisible UI is also drawing, some pixel areas will be drawn many times, thus wasting redundant CPU and GPU resources.

How to avoid over drawing, as follows:

Layout optimization. Remove the unnecessary background in XML, remove the default background of window, display the placeholder background picture on demand, and customize the view optimization. Use canvas. Cliprect() to help the system identify those visible areas that can only be drawn in this area.

3. Start optimization

By monitoring the startup speed, the problems affecting the startup speed are found, and the startup logic is optimized to improve the startup speed of the application. Startup mainly completes three things: UI layout, drawing and data preparation. Therefore, the start-up speed optimization is to optimize these three processes:

UI layout. Applications generally have flash screen pages. Optimize the UI layout of the flash screen pages, and detect frame loss through profile GPU rendering. Start load logic optimization. Distributed loading, asynchronous loading and deferred loading strategies can be adopted to improve the application startup speed. Data preparation. For data initialization analysis, thread initialization and other strategies can be considered when loading data.

4. Reasonable refresh mechanism

In the process of application development, due to changes in data, the page needs to be refreshed to display new data, but frequent refresh will increase resource overhead and may lead to jamming. Therefore, a reasonable refresh mechanism is needed to improve the overall UI fluency. Reasonable refresh needs to pay attention to the following points:

Minimize the number of refreshes. Try to avoid high CPU threads running in the background. Shrink the refresh area.

5. Others

When realizing the animation effect, we need to select the appropriate animation framework according to different scenes. In some cases, hardware acceleration can be used to provide fluency.

Memory optimization

There is a garbage memory recycling mechanism in the Android system, which automatically allocates and releases memory in the virtual machine layer. Therefore, it is not necessary to allocate and release a piece of memory in the code. From the application level, it is not easy to have problems such as memory leakage and memory overflow, but memory management is required. The Android system has a general heap memory model for memory management. Most of the pressure of memory recovery does not need the concern of the application layer. General heap memory has its own set of management mechanism. When the memory reaches a threshold, the system will automatically release the memory that the system thinks can be released according to different rules, It is precisely because the Android program gives the power of memory control to the generational heap memory. Once there are memory leakage and overflow problems, troubleshooting errors will become an extremely difficult task. In addition, some Android application developers do not pay special attention to the rational use of memory in the development process, nor do they do too much optimization in memory. When applications run more and more tasks at the same time, coupled with more and more complex business requirements, completely relying on Android's memory management mechanism will lead to a series of performance problems, Therefore, it is very necessary to solve the memory problem and optimize the memory reasonably.

Android memory management mechanism

Android applications run on the Android virtual machine, and the memory allocation and garbage collection of applications are completed by the virtual machine. In Android system, virtual machine has two operation modes: Dalvik and art.

1. Java object life cycle

General Java objects have seven running stages on the virtual machine:

Creation phase - > application phase - > invisible phase - > unreachable phase - > collection phase - > termination phase - > object space reallocation phase

2. Memory allocation

In Android system, memory allocation is actually the allocation and release of heap. When an Android program starts, the application processes are derived from a process called zygote. After the system starts the zygote process, in order to start a new application process, the system will derive the zygote process to generate a new process, and then load and run the application code in the new process. Among them, most ram pages are used to allocate to framework code, and promote ram resources to be shared among all application processes.

However, in order to control the memory of the whole system, the Android system will set a hard Dalvik heap size maximum limit threshold for each application. The whole threshold will vary on different devices due to different ram sizes. If an application attempts to allocate memory when the memory occupied by the application is close to the whole threshold, it is easy to cause a memory overflow error.

3. Memory recycling mechanism

What we need to know is that in Java, memory is divided into three areas: young generation, old generation and permanent generation. Recently allocated objects are stored in the young generation area. The object triggers the GC to collect garbage at a certain time, and those that are not collected may be moved to the old generation according to different rules, and finally accumulated for a certain time to the permanent generation area. The system will perform different GC operations according to different memory data types in memory. GC determines whether to collect objects by determining whether objects are referenced by active objects, and then dynamically reclaims the memory space occupied by objects without any references. However, it should be noted that frequent GC will increase the application jamming and affect the application fluency. Therefore, it is necessary to minimize the system GC behavior in order to improve the application fluency and reduce the probability of jamming.

Memory analysis tool

Before memory optimization, we need to understand the current memory usage of the current application, analyze which data types have problems through the current situation, how the distribution of various types is, and how to find out which specific objects cause the problems after discovering the problems. Therefore, we need relevant tools to help us.

1,Memory Monitor

Memory monitor is a very simple graphical tool to monitor the memory usage of the system or application. It mainly has the following functions:

The available and used memory are displayed, and the memory allocation and recycling are reflected in real time in the dimension of time. Quickly determine whether the slow running of the application is caused by excessive memory recycling. Quickly determine whether the application crashes due to insufficient memory.

2,Heap Viewer

The main function of the heap viewer is to view the usage of different data types in memory. You can see the heap size in the current process, the types of data, and the proportion of various types of data. By analyzing these data to find large memory objects, and then further analyze these large objects, so as to reduce memory overhead through optimization, or find memory leakage through data changes.

3,Allocation Tracker

Both memory monitor and heap viewer can intuitively and real-time monitor memory usage and find memory problems. However, after finding memory problems, they can't further find the cause or find an abnormal memory, but they can't distinguish whether it is normal or not. At the same time, after finding problems, they can't locate specific classes and methods. At this time, another memory analysis tool allocation tracker needs to be used for more detailed analysis. Allocation tracker can allocate and track the memory allocation of applications, list their call stacks, and view the cycle of memory allocation of all objects.

4,Memory Analyzer Tool(MAT)

Mat is a fast and feature rich Java heap analysis tool. By analyzing the memory snapshot hprof analysis of Java processes and analyzing from a large number of objects, mat can quickly calculate the size occupied by objects in memory, see which objects can not be recycled by the garbage collector, and visually view the objects that may cause this result through the view.

Common memory leak scenarios

If you find the cause and repair the memory leak after it occurs, it will increase the development cost. It is best to consider the memory problem well and write higher quality code when writing code. Here are some common memory leak scenarios that need to be avoided in the future development process.

The resource object is not closed. For example, cursor and file files often use some buffers. When they are not used, they should be closed in time. The registered object is not unregistered. For example, if an event is not unregistered after registration, the object reference will be maintained in the observer list. The static variables of the class hold large data objects. A static instance of a non static inner class. Handler temporary memory leak. If the handler is non static, the activity or service will not be recycled. Memory leak caused by objects in the container not cleaned up. WebView。 WebView has the problem of memory leakage. As long as WebView is used once in the application, the memory will not be released.

In addition, memory leaks can be monitored. A common way is to use the leakcanary third-party library, which is an Open-Source Library for detecting memory leaks. It is very simple to use. It can alarm when a memory leak occurs, generate a leak tarce, analyze the leak location, and provide dump files for analysis.

Optimize memory space

No memory leakage does not mean that memory does not need to be optimized. On mobile devices, due to the limited storage space of physical devices, the Android system also allocates limited heap memory to each application process. Therefore, using the minimum memory objects or resources can reduce the memory overhead and enable GC to more efficiently recycle objects that are no longer needed, Keep enough available memory in the application heap memory to make the application run more stably and efficiently. Common practices are as follows:

Object reference. There are four reference types: strong reference, soft reference, weak reference and virtual reference. Different reference types are selected according to business needs. Reduce unnecessary memory overhead. Pay attention to automatic packing and increase memory reuse, such as effective use of the system's own resources, view reuse, object pool and bitmap object reuse. Use the best data type. For example, for the data class container structure, you can use the arraymap data structure to avoid the use of enumeration types, lrucache, etc. Picture memory optimization. You can set bitmap specifications, compress according to the sampling factor, and manage pictures by some picture caching methods, etc. Stability optimization

The definition of Android application stability is very broad, and there are many reasons affecting the stability, such as unreasonable memory use, incomplete consideration of code exception scenarios, unreasonable code logic, etc., which will affect the stability of the application. The two most common scenarios are crash and ANR. These two errors will make the program unusable. The common solutions are as follows:

Improve code quality. For example, code review during development, see some code design logic, business rationality, etc. Code static scanning tool. Common tools include Android lint, findbugs, checkstyle, PMD, etc. Crash monitoring. Record some crash information and abnormal information in time for subsequent analysis and solution. Crash upload mechanism. After crash, try to save the log locally, and then upload the log information when the network is normal next time. Power consumption optimization

In mobile devices, the importance of batteries is self-evident. Nothing can be done without electricity. For the operating system and device developers, the power consumption optimization has not stopped to pursue longer standby time. For an application, the power consumption problem can not be ignored, especially those classified as "battery killer", and the final result is to be unloaded. Therefore, application developers need to minimize power consumption while meeting their needs.

Before Android 5.0, it was troublesome and inaccurate to test power consumption in applications. After 5.0, an API for obtaining power consumption information on devices: Battery historian was introduced. Battery historian is a power analysis tool for Android system provided by Google. Like systrace, it is a graphical data analysis tool, which intuitively shows the power consumption process of mobile phones, displays the consumption by inputting power analysis files, and finally provides some reference power optimization methods.

In addition, there are some common schemes to provide:

Calculation optimization, avoiding floating-point operation, etc. Avoid improper use of walelock. Use the job scheduler. Package size optimization

The size of the application installation package has no impact on the use of the application, but the larger the installation package of the application, the higher the threshold for users to download. Especially in the case of mobile network, users have higher requirements for the size of the installation package when downloading the application. Therefore, reducing the size of the installation package can make more users willing to download and experience the product.

The composition of common application installation packages is shown in the figure:

We can see from the figure:

Assets folder. Some configuration files and resource files are stored. Assets will not automatically generate the corresponding ID, but will be obtained through the interface of assetmanager class.

res。 Res is the abbreviation of resource. This directory stores resource files. The corresponding ID will be automatically generated and mapped to the. R file. The resource ID will be used directly for access.

Meta-INF。 Save the signature information of the application. The signature information can verify the integrity of the APK file.

AndroidManifest.xml。 This file is used to describe the configuration information of Android applications, the registration information and available permissions of some components.

classes.dex。 Dalvik bytecode program enables Dalvik virtual machine to execute. Generally, Android applications convert Java bytecode to Dalvik bytecode through DX tool in Android SDK during packaging.

resources.arsc。 It records the mapping relationship between resource file and resource ID, which is used to find resources according to resource ID.

Common solutions for reducing installation package size

Code confusion. Use the Proguard code obfuscator tool, which includes compression, optimization, obfuscation and other functions. Resource optimization. For example, use Android lint to delete redundant resources and minimize resource files. Image optimization. For example, use AAPT tool to compress PNG format pictures, reduce the number of color bits of pictures, etc. Avoid duplicate function libraries, use webp image format, etc. Plug in. For example, if the function modules are placed on the server and downloaded on demand, the installation package size can be reduced. Summary

Performance optimization can not be solved by updating one or two versions. It is a continuous demand and continuous integration iterative feedback. In the actual project, at the beginning of the project, due to the limitations of manpower and project completion time, the priority of performance optimization is relatively low. When the project is put into use, the priority needs to be increased. However, at the early stage of the project, when designing the architecture scheme, the points of performance optimization also need to be taken into account in advance, which reflects the technical skills of a programmer.

When there is a demand for performance optimization, it often starts from finding the problem, then analyzing the cause and background of the problem, and then looking for the optimal solution to finally solve the problem. This is also a processing method often used in daily work.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>