Speaking of Android phone, most people's impression is a bit of time to become a little lag, some programs in the run inexplicably crashes, open the System folder A look, found a lot of files, and then use the mobile phone butler APP constantly clean optimization, just feel the speed slightly improved point, Even if the mobile phone in a variety of performance in front of the software score ahead, or feel no matter how much memory space is far from enough to use. Believe that every user using Android system has experienced similar experience, indeed, the Android system is not as fluent as the iOS system, why, obviously in the mobile phone hardware configuration, Android devices will not be lost in IOS devices, or even stronger than it, the key is the software. The causes of this phenomenon are manifold, a brief list of several points are as follows:
- In fact, in recent years, as the Android version continues to iterate, the Android system provided by Google has become more and more fluent, the latest release is the Android 8.0 Oreo . However, most of the domestic users of the Android phone is the major manufacturers customized version, often not the latest native system kernel, probably most still stay on the Android 5.0 system, even Android 6.0 or more of the proportion is still small, the update has a delay.
- Because the Android system source code is open, everyone as long as the corresponding agreement, you can modify the source code, then the domestic manufacturers will be based on the Android source code to make their own external release system, such as our familiar millet mobile phone MIUI system, Huawei Mobile phone EMUI system, Oppo Mobile phone Coloros system and so on. Because each manufacturer has modified the Android native system source code, here will raise a problem, that is the famous Android fragmentation problem, the essence is different Android System application compatibility is different, does not reach the consistency.
- With a variety of Android fragmentation and compatibility issues, Android developers need to adapt to different systems when developing their applications, while the development level of each Android developer is uneven and there are different types of application performance issues. The user experience is different in the process, then some problem users will be translated into Android system problems, and thus affect the evaluation of Android phones.
Performance optimization
Today's focus is on Android app performance optimization, which is what points you should be aware of when developing your application, and how to better improve the user experience. A good application, in addition to have attractive features and interaction, in the performance should also have high requirements, real-time application is very characteristic, in the early stage of the product may attract some users, but the user experience is not good, will also bring bad reputation to the product. So how should a good application be defined? The main three aspects are as follows:
- Business/function
- Logic-compliant interactions
- Excellent performance
As we all know, the Android system as a mobile device-based operating system, hardware configuration is limited, although the configuration is now more advanced, but still can not be compared with the PC, in the CPU and memory usage is unreasonable or expensive, will encounter the memory shortage caused by the stability problem, CPU Consume too much of the problem caused by the lag.
In the face of problems, everyone think of is to contact the user, and then look at the log, but not surprisingly, the performance of the feedback, the reasons are very difficult to find, the log is mostly useful, why? Because performance problems are mostly non-essential problems, the problem location is difficult to reproduce, and there is no critical log, of course, can not find the reason. These issues have a great impact on user experience and feature usage, so it is important to understand some of the solutions to performance optimizations and to optimize our applications in real-world projects to improve the user experience.
Four aspects
The performance issues of the user experience can be summarized in 4 categories:
- Smooth
- Stability
- Save power, save traffic
- Small installation package
The main reasons for performance problems are the same and different, but in the final analysis, it is all about memory usage, code efficiency, appropriate strategy logic, code quality, installation package volume , and collation as follows:
As you can see, building a high-quality application should target 4 directions: Fast, steady, provincial, and small.
Fast: Avoid stuttering when using, fast response, reduce user wait time, meet user expectations.
Stability: Reduce crash rate and ANR rate, do not crash and unresponsive during user use.
Province: Save the flow and power consumption, reduce user costs, avoid the use of the phone caused by hot.
Small: A small installation package can reduce the user's installation costs.
To achieve these 4 goals, the specific implementation is in the right-hand frame of the problem: stalling, memory use unreasonable, poor code quality, Code logic chaos, installation package too large, these problems are in the development process encountered the most problems, in the realization of business needs, but also need to consider this, spend more time to think about, How to avoid the function after the completion of the optimization, otherwise, the maintenance costs resulting from the implementation will increase.
Lag optimization
Android apps are slow to start, often stuck in use, and are very influential to the user experience and should be avoided as much as possible. There are a lot of scenes, according to the scene can be divided into 4 categories: UI drawing, Application launch, page jump, event response,
The root causes of these 4 types of Dayton scenes can be divided into two main categories:
- Interface Drawing. The main reasons are the depth of the drawing, the complexity of the page, and the unreasonable refresh of the scene, which causes the stuttering scenario to appear more in the UI and after the initial start-up interface and jump to the drawing of the page.
- Data processing. The cause of this is the data processing volume is too large, generally divided into three cases, one is the data in the processing UI thread, the second is the processing of high CPU, resulting in the main thread can not get the time slice, three is the memory increase caused by GC frequent, resulting in the card.
Cause a lot of reasons for the lag, but no matter how the reason and the scene, the end is through the device screen display to reach the user, in the final analysis is a problem, so, to solve the card, we must first understand the Android system display principle.
Android System Display principle
The Android display process can be summarized as follows: The Android app caches data from measured, laid-out, painted surface, and renders data to the display via Surfaceflinger, and refreshes the data via the Android refresh mechanism. In other words, the application layer is responsible for drawing, the system layer is responsible for rendering, through interprocess communication to the application layer needs to draw data to the system Layer service, the system layer service through the refresh mechanism to update the data to the screen.
We all know that there are three core steps in each View drawing for Android: Measure, Layout, draw. The implementation is performed from the Performtraversals () method of the Viewrootimp class, Measure and layout are retrieved by recursion to get the size and position of the View, and with the depth as the priority, you can see that the deeper the hierarchy, the more elements, the longer the time.
Actually rendering the data that needs to be displayed to the screen is achieved through the Surfaceflinger service in the system-level process, so what does the Surfaceflinger service do? As follows:
- In response to client events, create a Layer to establish a connection to the client's Surface.
- Receive client data and properties, modify Layer properties such as size, color, transparency, and so on.
- Refreshes the created Layer content to the screen.
- Maintains the sequence of layers and makes a clipping calculation of the layer's final output.
Since it is two different processes, then it is necessary to have a cross-process communication mechanism to achieve data transmission, in the Android display system, using the Android anonymous shared memory: Sharedclient, each application and Surfaceflinger A sharedclient is created between the two, and in each sharedclient, you can create up to 31 sharedbufferstack, each of which corresponds to a sharedbufferstack, which is a Window.
A sharedclient corresponds to an Android application, and an Android application may contain multiple windows, Surface. That is, Sharedclient contains a collection of Sharedbufferstack, in which double buffering and triple buffering techniques are used in the display refresh mechanism. Finally summed up to show that the overall process is divided into three modules: The application layer is drawn to the buffer, surfaceflinger the buffer data to the screen, because it is a different process, so use the anonymous shared memory of Android Sharedclient cache needs to display the data to achieve the purpose.
In addition, we also need a noun: FPS. FPS indicates the number of frames passed per second. Ideally, the card will not be felt at FPS, which means that each drawing time should be within the range of Ms. But the Android system is likely to be unable to complete those complex page rendering operations in time. The Android system emits VSYNC signals every 16ms, triggering a rendering of the UI, and if each render succeeds, it will be able to achieve the 60FPS required for a smooth screen. If the time spent on an operation is 24ms, the system will not normally render normally when the VSYNC signal is obtained, so the drop frame phenomenon occurs. Then the user sees in the 32ms will be the same frame screen, this phenomenon in the execution of animation or sliding list is more common, there may be your Layout is too complex, stacked too many drawing units, can not be completed in 16ms rendering, resulting in a refresh is not timely.
Root cause of lag
According to the Android system display principle, you can see the following two aspects of the root cause of the impact of drawing:
- Drawing a task is too heavy, it takes too long to draw a frame.
- The main thread is too busy, according to the system passed the VSYNC signal came when the data is not ready to cause dropped frames.
Drawing takes too long and there are tools that can help us locate the problem. The main thread is too busy to be aware that the main thread key responsibility is to handle user interaction, draw pixels on the screen, and load display related data, so there is a need to avoid any main thread of things, so that the application can maintain an immediate response to user action. Summing up, the main thread to do the following aspects of work:
- UI Life Cycle Control
- System Event Handling
- Message processing
- Interface layout
- Interface Drawing
- Interface Refresh
In addition, you should try to avoid placing other processes in the main thread, particularly complex data calculations and network requests.
Performance analysis Tools
Performance problems are not easy to reproduce, but also difficult to locate, but really encountered problems or need to solve, then analyze the problem and confirm whether the problem is solved, you need to use the appropriate debugging tools, such as viewing the Layout level of Hierarchy view, Android system with the GPU The profile tool and the static Code check tool, Lint, are very important for performance optimization, so be familiar with what tools are used to analyze the scenario.
1,profile GPU Rendering
In Mobile developer mode, there is a lag detection tool called: Profile GPU Rendering,
Its functional characteristics are as follows:
- A graphical monitoring tool that can react to the current drawing time-consuming
- The horizontal axis represents time, and the longitudinal axes represent the duration of each frame
- A left-to-right refresh renders over time
- Providing a standard time-consuming, if above-standard time-consuming, means that the current frame is missing
2,traceview
TraceView is a tool that comes with the Android SDK to analyze the function call process, which allows you to perform performance analysis on Android applications and the code in the Framework layer. It is a graphical tool, will eventually produce a graph for performance analysis, you can analyze the execution time of each method, which can be counted the method calls and recursion times, the actual length of the parameters such as parameter dimensions, the use is very intuitive, analysis performance is very convenient.
3,systrace UI Performance Analysis
Systrace is a performance data sampling and analysis tool provided by Android version 4.1 and above, which returns some information from a system perspective. It helps developers to collect operational information such as key modules, services, and view systems of Android key subsystems, such as Surfaceflinger, Windowmanagerservice, and so on, thus helping the developer to analyze system bottlenecks more intuitively. Improve performance. Systrace's features include tracking system I/O operations, kernel work queues, CPU load, and so on, providing good data on UI display performance analysis, especially in the face of choppy animations, rendering cards, and more.
Optimization recommendations
1, layout optimization
Layout is the main impact of the page measurement time, we know that the display of a page measurement and drawing process is done by recursion, the time of the multi-fork tree traversal is related to the height of the tree, its time complexity O (h), if the hierarchy is too deep, each additional layer will add more page display time, So the rationality of the layout is very important.
What are the methods of layout optimization, mainly through reducing the level, reducing the measurement and drawing time, improve the reusability of three aspects. Summarized as follows:
- Reduce the level. Use Relativelayout and linerlayout rationally and use merge appropriately.
- Improve display speed. With Viewstub, it is a view object that is invisible, occupies no layout position, and occupies very small resources.
- Layout reuse. You can use labels to improve reuse.
- Use as little wrap_content as possible. Wrap_content will increase the cost of the layout measure when it is known that the wide height is fixed, without wrap_content.
- Removes unused properties from the control.
2, avoid over-drawing
Over-drawing means that a pixel on the screen is drawn several times within the same frame. In a multi-layered UI structure, if the invisible UI is also drawing, it causes some pixel regions to be drawn multiple times, wasting redundant CPU and GPU resources.
How to avoid over-drawing, as follows:
- Optimization on the layout. Remove the required background from the XML, remove the Window's default background, display a placeholder background image on demand
- Custom View optimization. Use Canvas.cliprect () to help the system identify those areas that are visible and will be drawn only within this area.
3, start optimization
By monitoring the startup speed, we find the problem that affects the starting speed, optimize the start-up logic and improve the startup speed of the application. Start with three main things: UI layout, drawing, and data preparation. So starting speed optimization is the process of optimizing these three processes:
- UI layout. Apps typically have splash screens that optimize the UI layout of the splash screen and can detect dropped frames through the profile GPU Rendering.
- Initiates load logic optimizations. You can use distributed loading, asynchronous loading, and deferred loading strategies to improve application startup speed.
- Data preparation. Data initialization analysis, loading data can be considered with thread initialization and other policies.
4, a reasonable refresh mechanism
In the application development process, because the data changes, the need to refresh the page to show new data, but frequent refresh will increase the resource overhead, and may lead to the occurrence of Kaka, therefore, a reasonable refresh mechanism is needed to improve the overall UI smoothness. A reasonable refresh requires attention to the following points:
- Minimize the number of refreshes.
- Try to avoid a high CPU thread running in the background.
- Reduce the refresh area.
5, other
When animating, it is necessary to choose the appropriate animation frame for different scenes. In some cases, you can use hardware acceleration to provide smoothness.
Memory optimized
There is a garbage memory recovery mechanism in the Android system that automatically allocates and frees memory at the virtual machine layer, so there is no need to allocate and release a piece of memory in code, and it is not prone to problems such as memory leaks and memory overflow at the application level, but memory management is required. Android system in memory management has a generational Heap memory model, memory recovery of most of the pressure does not need to be concerned about the application layer, generational Heap memory has its own set of management mechanism, when the memory reaches a threshold value, The system will automatically release the memory that the system thinks can be freed according to different rules, and it is precisely because the Android program gives the memory control power to the generational Heap memory, and if there is a problem with the leak and overflow, troubleshooting will be an extremely difficult task. In addition, some Android application developers in the development process is not particularly concerned about the rational use of memory, nor do too much in memory optimization, when the application running more and more tasks, coupled with increasingly complex business requirements, full reliance on Android Memory management mechanism will cause a series of performance problems to be gradually presented, the stability and performance of the application can not be neglected, so it is necessary to solve the memory problem and optimize the memory reasonably.
Android Memory management mechanism
Android apps are run on Android virtual machines, and the memory allocation and garbage collection of the application is done by the virtual machine. On Android, virtual machines have two modes of operation: Dalvik and ART.
1,java Object Life cycle
A generic Java object has 7 run stages on a virtual machine:
Object Space Redistribution Phase------phase-to-stage, end-of-phase, not visible phase
2, memory allocation
In an Android system, memory allocations are actually allocations and releases of the heap. When an Android program starts, the application process is 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, The code for the application is then loaded and run in the new process. Most of these RAM pages are used to assign to the framework code, while allowing RAM resources to be shared across all processes in the app.
But for the entire system's memory control needs, the Android system will set a hard Dalvik Heap size maximum limit threshold for each application, the entire threshold will vary depending on the size of the RAM on different devices. If the application occupies a memory space that is close to the entire threshold, then attempts to allocate memory can easily cause a memory overflow error.
3, memory recovery mechanism
What we need to know is that memory in Java is divided into three regions: young Generation (younger generation), old Generation (older generation), Permanent Generation (persistent generation). Recently allocated objects are stored in the young Generation area. When an object triggers GC garbage collection at some point, it is possible to move to an old Generation and not be recycled according to different rules, and finally accumulate a certain amount of time to move to the Permanent Generation area. The system performs different GC operations based on the different memory data types in memory. The GC determines whether objects are collected by determining whether the object is being referenced by the active object, and then dynamically reclaims the memory space occupied by objects without any references. However, it is important to note that frequent GC increases the lag of the application and affects the fluency of the application, so the system GC behavior needs to be minimized so as to improve the smoothness of the application and reduce the probability of the occurrence of the card.
Memory analysis Tools
Before doing memory optimization, it is necessary to understand the current memory usage status of the application, analyze what data types are problematic through the status quo, how the various types of distributions are distributed, and how to identify the specific objects after the problem is discovered, which requires tools to help us.
1,memory Monitor
Memory Monitor is a very simple graphical tool that allows you to monitor your system's or application's RAM usage with the following features:
- Displays available and used memory, and responds to memory allocations and recoveries in real time, in the dimensions of the dimension.
- Quickly determine if the application is running slowly due to excessive memory reclamation.
- Quickly determine if the application crashes due to insufficient memory.
2,heap Viewer
The main function of the Heap viewer is to see how different data types are used in memory, to see the Size of the heap in the current process, what types of data are available, and what kinds of data are accounted for. By analyzing the data to find large memory objects, further analysis of these large objects, through optimization to reduce memory overhead, but also through the change of data to discover memory leaks.
3,allocation Tracker
Both the memory monitor and the Heap Viewer can be very intuitive and in real-time to monitor the use of memories, but also to find memory problems, but found that the memory problem can not be further to find the cause, or found a piece of abnormal memory, but can not distinguish whether normal, and after the discovery of problems, It is also not possible to locate specific classes and methods. In this case, you need to use another memory analysis tool Allocation Tracker For more detailed analysis, Allocation Tracker can allocate memory allocations for the trace logging application and list their call stacks to see the period of all object memory allocations.
4,memory Analyzer Tool (MAT)
MAT is a fast, feature-rich Java Heap Analysis tool that analyzes the memory snapshot HPROF analysis of Java processes, analyzes from numerous objects, quickly calculates the size of objects in memory, and views which objects cannot be reclaimed by the garbage collector. You can visually view the objects that may be causing the result through the view.
Common memory leak scenarios
If the memory leak occurs after the reason and repair will increase the cost of development, it is best to write code when it is good to consider memory problems, write higher quality code, here are some common memory leak scenarios, in the future development process need to avoid such problems.
- The resource object is not closed. such as cursor, file files, and so on, often use a few buffers, when not in use, should close them in time.
- The registration object is not logged off. For example, an event that does not log off after registration causes the object's reference to 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 leaks. If the handler is non-static, it is easy to cause Activity or Service not to be recycled.
- A memory leak caused by an object in the container is not cleaned up.
- WebView. WebView There is a memory leak problem, in the application as long as the use of WebView, memory will not be released.
In addition, memory leaks can be monitored, and the common use of leakcanary third-party libraries, which is an open-source library for detecting memory leaks, is very simple to alert when a memory leak occurs and generates leak Tarce to analyze the leak location while providing a Dump file for analysis.
Optimize memory space
No memory leaks, does not mean that the memory does not need optimization, on the mobile device, because the physical device storage space is limited, the Android system for each application process is also allocated a limited amount of heap memory, so the use of the smallest memory objects or resources can reduce memory overhead, while allowing the GC More efficient recycling of objects that are no longer needed, allowing the application heap memory to keep enough available memory for the application to run more stably and efficiently. Common practices are as follows:
- The object reference. Strong reference, soft reference, weak reference, virtual reference four reference types, according to business requirements reasonable use different, choose a different reference type.
- Reduce the unnecessary memory overhead. Pay attention to automatic boxing, increase memory reuse, such as efficient use of the system's own resources, view reuse, Object pool, bitmap object reuse.
- Use the optimal data type. For example, for a data class container structure, you can use the ARRAYMAP data structure, avoid using enumeration types, use cache LRUCache, and so on.
- Picture memory optimization. Bitmap specifications can be set, based on the sampling factor to do compression, with some image caching methods to manage the image, and so on.
Stability optimization
The stability of Android applications is broadly defined, and there are many reasons for stability, such as unreasonable memory usage, poorly considered code anomalies, unreasonable code logic, and so on, which will affect the stability of the application. The most common of the two scenarios are: Crash and ANR, these two errors will make the program unusable, the more common solution is as follows:
- Improve code quality. For example, the code review during development, look at some code design logic, business rationality and so on.
- The Code static Scan tool. Common tools include Android Lint, Findbugs, Checkstyle, PMD, and more.
- Crash monitoring. The breakdown of information, abnormal information in a timely manner to record, so that the subsequent analysis to solve.
- Crash upload mechanism. After crash, try to save the log to local, and then wait for the next time the network is normal to upload log information.
Power consumption optimization
In mobile devices, the importance of batteries is self-evident, without electricity, nothing can be done. For operating system and device developers, power consumption optimization does not stop, to pursue longer standby time, and for an application, it is not possible to ignore the use of electricity, especially those classified as "battery killer" application, the end result is uninstalled. As a result, application developers need to minimize power consumption while implementing requirements.
Before Android5.0, it was cumbersome and inaccurate to test the power consumption in the application, and after 5.0, a api:battery Historian was introduced specifically to obtain information about the power consumption on the device. Battery Historian is a Google-provided Android system power analysis tool, like Systrace, is a graphical data analysis tool that visually shows the phone's power consumption process, by entering a power analysis file, showing the consumption situation, Finally, some methods to optimize the reference power are provided.
In addition to this, there are a few common options available:
- Calculate optimization, avoid floating-point arithmetic, etc.
- Avoid improper use of walelock.
- Use Job Scheduler.
installation package Size optimization
The app installation package size has no effect on app usage, but the larger the app's installation package, the higher the user download threshold, especially in the case of mobile networks, when users download the app, the size of the installation package is higher, so reducing the size of the installation package will allow more users to download and experience the product.
The composition of the Common Application installation package:
We can see:
Assets folder. Storing some configuration files, resource files, assets does not automatically generate the corresponding ID, but is obtained through the interface of the Assetmanager class.
Res. RES is an abbreviation for resource, which holds the resource file and automatically generates the corresponding ID and maps to it. R file, Access uses the resource ID directly.
Meta-inf. Save your app's signature information to verify the integrity of the APK file.
Androidmanifest.xml. This file is used to describe the configuration information of the Android app, the registration information of some components, the permissions to use, and so on.
Classes.dex. Dalvik bytecode program, let Dalvik virtual machine executable, in general, Android application in the Android SDK when packaging through the DX tool to convert Java bytecode to Dalvik byte code.
RESOURCES.ARSC. A mapping relationship between resource files and resource IDs is recorded to find resources based on resource IDs.
Common scenarios for reducing the size of installation packages
- Code obfuscation. Use the Proguard Code obfuscation tool, which includes features such as compression, optimization, and obfuscation.
- Resource optimization. For example, use Android Lint to remove redundant resources, minimize resource files, and so on.
- Picture optimization. For example, use the AAPT tool to compress images in PNG format, and reduce the number of image color bits.
- Avoid duplicate functions of the library, use WEBP picture format, etc.
- Plug-in. For example, the function module on the server, on-demand download, you can reduce the size of the installation package.
Summary
Performance optimization is not an update of one or two releases, it is a continuous requirement, continuous integration of iterative feedback. In the actual project, at the beginning of the project, due to manpower and project completion time constraints, performance optimization priority is relatively low, and so on into the project into the use phase, you need to improve the priority, but in the early stages of the project, in the design of the schema, performance optimization points need to be considered earlier, This reflects the technical skills of a programmer.
When it comes to the need for performance optimization, it often starts with the discovery of problems, then analyzes the cause and background of the problem, and then finds the best solution to solve the problem, which is the usual way of handling the work.
Android App Performance Optimization Thinking-the reason why the performance is not good?