Android performance optimization Manual
This manual is suitable for developers with at least preliminary experience to check or review relevant knowledge. New users may not understand this manual.
1. java code optimization 1.1 how Android executes code
Dvm:. java->. class->. dex->. apk
Optimized the Fibonacci series:
The recurrence formula of the Fibonacci series is f (n) = f (n-1) + f (n-2), and the feature equation is: x2 = x + 1, obtain the equation (1 + sqrt (5)/2, (1-sqrt (5)/2. so f (n) = Ax1n + Bx2n, bring f (0) = 0, f (1) = 1 to A = sqrt (5)/5, B =-sqrt (5)/5. then f (n) is obtained.
BigInteger:
This class is used to solve the overflow problem.
The Fibonacci series has the following attributes:
(Fn fn-1) = (fn-1 fn-2) * A, can be obtained A = (1 1; 1 0)
Recursive get :( fn fn-1) = (fn-1 fn-2) * A = (fn-2 fn-3) * A2 =... = (F1 f0) * An-1
Cache results:
HashMap is used as the cache. when the key is an integer, SparseArray is more efficient.
LruCache:
Suitable for caching images. Its main algorithm principle is to store recently used objects with strong references in LinkedHashMap, in addition, the minimum recently used objects are removed from the memory before the cache value reaches the preset value.
-
Private LruCache
MJsonCache;/*** cache image information */private LruCache
MBitmapCache; public Util () {mJsonCache = new LruCache
(1x1024*1024); mBitmapCache = new LruCache
(2x1024*1024 );}
Data structure:
Android has added its own implementations in these data structures, generally to improve performance, LruCache \ SparseArray \ SparseBooleanArray \ SparseIntArray \ Pair
There are also Arrays and Collections classes. For example, Arrays. sort is used to sort Arrays.
Response Capability: familiar with the lifecycle, for example, configuring the Android: configChanges attribute when the device direction changes
Deferred initialization: for example, you can use android. view. ViewStub to postpone initialization. It takes time to allocate the memory. It is also a good choice to allocate the memory only when the object actually needs it. StricMode: the main thread is not used to access time-consuming operations such as the network. SQLite statement: accelerate the creation of SQL statement strings to be executed. In this case, using the + operator to connect strings is not the most effective method. Instead, use the StringBuilder object or call the String. format can improve the performance. Transaction: one-time transaction resolution. You can use SQLiteOpenHelper to replace manual database creation. Query: Create a cursor to obtain only the first column 2 and NDK
It is mainly written by c/c ++ and is a native Android development kit.
1. Create a local method:
public native String encode(String text, int length);public native String decode(String text, int length);}
2. Implement the JNI bonding layer:
Use the jdk javah tool to automatically generate a file.
Create a jni folder under the project root directory and create a c file in the jni File
In java code, create a local method helloFromC
public native String helloFromC();
Define the function implementation method in jni. The function name must be
jstring Java_com_zhilinghui_helloworld1_MainActivity_helloFromC(JNIEnv* env, jobject obj)
Returns a string, which is defined by c.
char* cstr = "hello from c";
Converts a c string to a java string.
jstring jstr = (*env)->NewStringUTF(env, cstr);return jstr;
Create an Android. mk file in jni and add the c/c ++ code to the c file (conclusion)
The previous steps are a bit messy. Here is a brief summary:
Step 1:
Defining a c method interface in java is equivalent to defining an interface Implementation Method in java code in c language.
Public native String hello ();
Step 2:
Implement C code
Method names are strictly in accordance with jni specifications
Step 3:
Creating android. mk tells the compiler how to package c code into a function library
LOCAL_PATH: = $ (call my-dir)
Step 4:
Package c code into a function library and use the installation environment to the corresponding directory. Use ndk-build to package
Step 5:
Import function in java code
Step 6:
Usage 3. Advanced NDK
Assembly optimization: Android NDK has built-in GCC compiler functions.
Make sure that the correct version of objdump is used to decompile the target file and library.
ARM mode and Thumb mode.
Color Conversion: The most common operations in graphics programs are to convert colors from one format to another. ARGB8888 and RGB565. RAM instructions improve performance using inline functions: that is, replace the call directly at the call. Add the "inline" keyword before the function definition. Loop expansion: expansion can actively schedule (or pipe-based) cycles to mask some latency. It is useful if there are enough idle registers to keep variables active because key paths are exposed by expanding the correlation chain. Memory pre-read: 1. -- builtin_prefetch () of GCC; 2. Use PLD and PLDW commands in ARM assembly code, and use PLI commands. Replacing LDR/STD with LDM/STM: loading multiple registers using a single instruction is faster than loading registers using multiple LDR instructions. 4. Efficient memory usage
Java's char is 16-bit (UTF-16), java's long is 64-bit, and c's long is 32-bit, long is 64-bit.
Access Memory:
Methods to reduce the possibility of data cache read Miss: 1. Use the smallest possible data type when a large amount of data is stored in an array; 2. Select sequential access instead of random access, the data already in the cache can be reused to the maximum extent.
Garbage Collection: Memory leakage
OOM occurs only when an object is no longer referenced and its memory is recycled.
For example, when the screen is rotated. Heap and Allocation Tracker tracking in DDMS in Eclipse.
You can also use the StricMode class to detect potential memory leaks.
Reference
Strong reference: the vast majority of programs use this reference. Is a "normal" reference.
-BigIntegerbi = BigInteger. valueOf (n); // strongly referenced
Integer I = new Integer (n); // strongly referenced
I = null; // The Integer object turns into garbage that can be recycled.
Soft, weak, and virtual references:
Soft and object, the garbage collector decides to recycle the old. Weak and accessible objects are basically recycled. Virtual references are rarely used and can be used to register a reference queue.
Garbage Collection
It may be triggered at an indefinite period of time and almost cannot be controlled. For example, when the heap is full and cannot be allocated memory, the memory should be recycled when new objects are allocated. GetMemoryInfo (), getMemoryClass (), getLargeMemoryClass (), dumHprofData (), getMemoryInfo, getNativeHeapAllocatedSize (), and getNativeHeapSize () of APIActivityManager ().
-
ActivityManager am=(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);ActivityManager.MemoryInfo memInfo=new ActivityManager.MemoryInfo();am.gettMemoryInfo(memInfo);
5. multithreading and synchronization threads
Thread object. The run () method can be rewritten, And the Runnable object is passed to the Thread constructor. Remember to call start ().
Thread priority, usually 1-10 (highest). The default value is 5. the Linux priority is from-20 to 19 (lowest ).
AsyncTask
Input parameters of AsyncTask startup Task Stack execution, percentage of backend tasks executed, result returned by backend tasks, Anonymous class.
For example, refresh the foreground progress bar when downloading files in the background.
Handler and logoff
They are the cornerstone of multi-threaded Application Thread communication.
HandlerHandler: the handler responsible for sending and processing messages. When using Handler, you must implement the handleMessage (Message msg) method to process specific messages, such as updating the UI.
Handler is created in the run () method because it needs to be bound to the specified logoff, which is created by calling logoff. prepare (0) in the run () method. Call getHandler () to return null. logoff before the thread is generated.
A thread with a message loop.
Logoff: the Message pump constantly extracts messages from MessageQueue for execution. Therefore, a MessageQueue requires a logoff.
Message: contains the Message ID, the Message processing object, and the processed data. MessageQueue queues in a unified manner and is eventually processed by Handler.
MessageQueue: a message queue used to store messages sent by Handler and run the messages according to FIFO rules. Of course, storing messages is not actually a matter of saving. Instead, messages are connected in a linked list, waiting for the logoff to be extracted.
Thread: a Thread that schedules the entire message loop, that is, the execution location of the message loop.
Activity Lifecycle
7 lifecycles
When AsyncTask. cancel () is called, onCancelled () is triggered after doInbackground () is returned, instead of onPoseExecute ().
6. Performance Evaluation and Analysis
Traceview in DDMS
View the execution time of the tracing code and analyze the time-consuming operations. It can be used to trace method calls, especially the method call relationship at the Android Framework layer.
TraceView lists all the methods that are listened to. Of course, it also includes the time consumption of many methods in the Android system. How can I find my concerns in so many methods? You can search by finding at the bottom of TraceView. Generally, the Android app has a package name. You can sort the concerned columns first and then perform a search by package name, this saves you the time required to filter out the time-consuming ranking of your app method.
7. Extend battery life
Generally, screen and wifi consume a lot of power.
Measure battery usage
You can retrieve a fixed Intent. When the application starts, it obtains the current battery power. It runs for a period of time and gets the battery power again when it exits. However, this value is not accurate because other applications are running.
Disable broadcast Receiver
The broadcast receiver is enabled only when necessary.
Because BatteryManager broadcasts an intent entity of sticky, this means that you do not have to register a broadcast receiver for your program to accept the broadcast. You can simply call the registerReceiver method, when you need to add the parameter of the broadcast receiver location to upload to null, you can also create a new broadcast receiver and import it when registering the broadcast receiver. Network
Finally, AT&T and its colleagues from the University of Michigan conducted an in-depth comprehensive survey on the end-to-end data transmission path, the final discovery is the root cause of the complex interaction between devices and cellular networks. The interaction is hard to see and provides a layered network architecture, developers who intentionally hide low-layer protocols work at the application layer.
Location
Use
WakeLock
For example, when a user watches a video or movie, the cpu needs to decode the video and keep the screen on for the user to watch it.
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE); WakeLock sCpuWakeLock = pm.newWakeLock( PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP,"okTag"); if (sCpuWakeLock!= null) { sCpuWakeLock.release(); sCpuWakeLock = null; }
PARTIAL_WAKE_LOCK: to keep the CPU running, the screen and keyboard lights may be disabled.
SCREEN_DIM_WAKE_LOCK: keeps the CPU running, allows screen display, but may be gray, allows the keyboard light to be turned off
SCREEN_BRIGHT_WAKE_LOCK: keeps the CPU running, keeps the screen highlighted, and allows you to turn off the keyboard light.
FULL_WAKE_LOCK: keeps the CPU running, keeps the screen highlighted, and keeps the keyboard light bright.
ACQUIRE_CAUSES_WAKEUP: do not wake up the device, force the screen to be highlighted immediately, and enable the keyboard light. One exception is that the device will be awakened If a notification pops up.
ON_AFTER_RELEASE: After the WakeLock is released, the screen brightness is maintained for a short period of time to reduce the flickering State during the WakeLock loop.
If you have applied for a partial wakelock, the system will not Sleep even if you press the Power key. For example, if you have applied for another wakelocks during Music playback and press the Power key, the system will still Sleep.
However, if the Android designer's intention is not understood and the Wake Lock API is abused, preventing the AP from entering sleep for a long time for its program to work normally in the background will become a killer of the standby battery. Reminder
AlarmManage has an AlarmManagerService, which maintains all types of Alarm registered by the app and keeps listening to Alarm devices. Once an Alarm is triggered or an Alarm event occurs, AlarmManagerService traverses the Alarm list, find the corresponding Alarm registration and send a broadcast.
Alarm Manager maintains a wake lock of the cpu. This ensures that alarm broadcast can be processed when the phone is sleeping. Once the onReceive () method of the alarm receiver is executed, the wake lock will be quickly released. If a service is enabled in the consumer er, it is possible that the service has not been started and the wake lock has been released. Therefore, we need to implement a separate wake lock policy.
There are four types of Alarm:
1) RTC_WAKEUP
Wake up the device to trigger Intent at the specified time (when Alarm is set.
2) RTC
Triggers Intent at an explicit time, but does not wake up the device.
3) ELAPSED_REALTIME
After the device is started, if the elapsed time reaches the total time, Intent is triggered, but the device is not awakened. The elapsed time includes any time the device sleeps. Note that the computing point of time elapsed is counted from the last time it was started.
4) ELAPSED_REALTIME_WAKEUP
After the device is started, if you need to wake up the device and trigger Intent after the total time elapsed.
Sensors, graphics
I will not introduce it in detail here.
8. graphic layout optimization
Call setContentView (). The xml layout should reduce the number of objects to be created. Different la s can be used to achieve the same visual effect, eliminate unnecessary objects, or postpone object creation.
Nested linear layout will deepen the layout hierarchy, resulting in slow layout and key-press processing. Relatively layout is required when more than 10 projects are displayed.
Use
Label to merge Layout
-
* Use
Tag reuse Layout
ViewStub: Postponed Loading
Layout tool
Under the sdk-> tools directory, hierarchyviewer and layoutopt can be used to view and analyze the layout.
OpenGL ES
OpenGL ES (short for OpenGL for Embedded System) is a free 2D and 3D graphics library for Embedded systems.
Any complex 2D or 3D images are constructed from these three types of geometric images. OpenGL ES provides two methods to draw a space ry:
Public abstract void glDrawArrays (int mode, int first, int count) is drawn using VetexBuffer. The order of vertices is specified by the order in vertexBuffer.
Public abstract void glDrawElements (int mode, int count, int type, Buffer indices), you can redefine the vertex sequence, which is specified by indices Buffer.
Mode list: GL_POINTS draw independent points, GL_LINE_STRIP draw a line segment, GL_LINE_LOOP draw a closed line segment (first connected), GL_LINES draw multiple line segments, GL_TRIANGLES draw multiple triangles (not adjacent) GL_TRIANGLE_STRIP draws multiple triangles (adjacent to each other) and GL_TRIANGLE_FAN draws multiple adjacent triangles based on one vertex. In addition to defining coordinates for each vertex, it can also specify colors and materials, normal (used for illumination. The pipeline switches that can be controlled by glEnableClientState and glDisableClientState can include GL_COLOR_ARRAY (color), GL_NORMAL_ARRAY (normal), GL_TEXTURE_COORD_ARRAY (material), GL_VERTEX_ARRAY (vertex), and timeline. The method for passing in the color, vertex, material, and normal is as follows: glColorPointer (int size, int type, int stride, Buffer pointer) glVertexPointer (int size, int type, int stride, buffer pointer) glTexCoordPointer (int size, int type, int stride, Buffer pointer) glNormalPointer (int type, int stride, Buffer pointer) OpenGL ES contains COLOR, DEPTH (DEPTH information), etc., usually need to clear the COLOR and DEPTH Buffer before drawing the image.
General matrix transformation commands: This section describes some matrix operations and operations supported by Android OpenGL ES for the specified coordinate system (such as viewmodel, projection, or viewport. The Matrix itself supports addition, subtraction, multiplication, and division. The 4X4 Matrix with all the diagonal lines being 1 is the unit Matrix Identity Matrix.
Set the current matrix as the unit matrix command to glLoadIdentity ().
The glMultMatrix * () command for matrix multiplication allows you to specify any matrix to be multiplied by the current matrix.
Select the current Matrix Type glMatrixMode (). OpenGL ES to run the specified GL_PROJECTION, GL_MODELVIEW, and Other coordinate systems. Subsequent matrix operations will be performed on the selected coordinates.
Set the current matrix to any specified matrix glLoadMatrix *()
Save the current matrix in the stack and restore the existing matrix from the stack. You can use glPushMatrix () and glPopMatrix ()
Specific Matrix Transform translation glTranslatef (), rotating glRotatef () and scaling glScalef ()
Texture Compression
Specific can be seen on the official website: http://developer.android.com/training/graphics/opengl/index.html
Coloring, scene complexity, blanking, rendering,
Frames are rendered only when the scenario changes.
9. RenderScript
RenderScript is a low-level high-performance programming language for 3D rendering and processing-Intensive Computing (such as 3D playback and CPU-Intensive Computing ). Android's graphics performance has been unsatisfactory for a long time and improved only after NDK was introduced. However, after Honeycomb released the RenderScript killer in the Framework, this greatly increases the execution and computing capabilities of the Android local language.
RenderScript is compiled on the machine for the first Time, and then compiled on the target device for the last Time (Just-In-Time Compiling), resulting In more efficient native binary code. This means that any device that supports RenderScript can run your code. No need to worry about the architecture.
Currently, the Code provided by RenderScript can only run on the master processor. It automatically generates code that can use multiple cores (if multiple cores exist on the device ). Therefore, the compiled program is the best optimization for the machine, which solves the Device Fragmentation. That is to say, developers no longer have to worry that users' mobile phones and tablets are not good enough and there is no GPU... And so on, just leave it to RenderScript to worry about it. Without GPU, programs written by RenderScript are processed by the CPU (the underlying compilation technology is actually LLVM ).