Hot Articles Guide | Click Title to Read
[Recommended] Resource Splitting in Android Studio, Very Useful
Awesome! 74 Complete Source Codes for Apps!
Android High Imitation of Dongqiudi, I Am the Coach Effect
In previous articles, we discussed the issue of performance optimization in Android in detail. This article is a summary of the previous parts (readers can refer back to the previous articles), and I hope to share some practical experience from real projects to inspire everyone.
Android performance optimization is also a knowledge point that is almost always asked in interviews. This article will also tell you how to answer such questions.
In actual projects, Android performance optimization mainly includes the following aspects:
-
Writing Efficient Code—Some Small Performance Tips Summarized During Development
-
Layout Optimization
-
Memory Optimization
Writing Efficient Code
This section tells you how to write efficient code and summarizes some small performance optimization points.
The two principles of writing efficient code
-
Do not write unnecessary code
-
Do not allocate unnecessary memory
The above two principles may seem trivial, but they are indeed the highest realm of programming and are two aspects that we need to constantly think about and pay attention to during the coding process.
So how to achieve the above two points? Here are some small examples from actual development.
1. Avoid Creating Unnecessary Objects
For example:
-
An array of int is much better than an array of Integer objects. Two parallel int arrays are more efficient than one array of (int, int) objects. This is true for any combination of other primitive data types.
-
Two parallel arrays Foo[], Bar[] will outperform an array of (Foo, Bar) objects.
-
Generally, try to avoid creating short-lived temporary objects. Fewer object creations mean lower frequency of garbage collection.
Object allocation and deallocation come at a cost; the more memory allocated, the more forced memory collections will occur, introducing small pauses that negatively affect user experience.
The user can feel the stuttering delay time is 100ms ~ 200ms.
2. Use Static Instead of Virtual
-
If a method does not need to access any fields of an object, set the method as static; the calling speed will increase by 15% to 20%.
-
Use final static for constants.
final static int intVal = 42;
final static String strVal = "Hello world";
Note: This optimization is only for primitive data types and String constants, not for any reference types. However, declaring constants as static final is a good practice.
Why is it a good practice to declare constants as static final? This is because:
-
When the above code block does not have the final modifier, the compiler will generate a class initialization method that executes when the class is first used. This method will store 42 in intVal and get a reference to the class file string constant strVal. When these values are referenced later, they are accessed via field lookup.
-
Once declared as final fields, the class no longer needs the method because constants are loaded into the dex file through static field initializers. Code referencing intVal will directly call the integer value 42; accessing strVal will also use a relatively low-overhead “string constant” instruction instead of field lookup.
This section discusses some minor performance improvements that may not significantly enhance your program’s performance. The overall performance of the program still depends on the design of the program’s business logic, data structures, and algorithms. However, you need to apply these optimization techniques in your daily coding process; accumulating small improvements can have a significant impact on performance.
3. Avoid Internal Getters and Setters
4. Use Enhanced For Loops
For ArrayList and arrays, manually written counting loop iterations are three times faster than enhanced for loops.
Conclusion: Prefer using improved for loops, but in performance-critical ArrayList iterations, consider using manually written counting loops. (See Effective Java item 46.)
5. Avoid Using Floating Point Numbers
The general experience is that, on Android devices, floating point numbers are about twice as slow as integers.
6. On Devices Without JIT, Passing Objects of Specific Types Instead of Interface Types is More Efficient
void methodA(List<String> list);
void methodA(ArrayList<String> list);
As above, the latter is more efficient than the former.
7. Optimize Database Operation Methods
-
Try to Use Native SQL Statements
Native SQL skips the step of concatenating SQL statements and is more efficient than the insert, query, update, delete functions provided by SqliteDatabase. The larger the database, the greater the difference.
-
When the number of operations is large, use transactions for batch processing.
In this way, SQLite will cache all SQL statements to be executed in memory and write them to the database all at once when COMMIT is called, significantly improving efficiency as the database file is only opened and closed once.
db.beginTransaction();
for(Collection c:colls){
insert(db, c);
}
db.setTransactionSuccessful();
8. Choice of Http Request Method
Android has two built-in HTTP methods: HttpURLConnection and Apache HttpClient. Both support HTTPS, streaming uploads and downloads, configurable timeouts, IPv6, and connection pooling. It is recommended to use HttpURLConnection for Gingerbread or higher versions.
This is because: The HttpURLConnection API is simpler, the package is smaller. At the same time, data transfer compression and response caching reduce network bandwidth, improve speed, and save power.
Optimize Layouts
Layouts are a key part of Android applications that directly affect user experience. Poorly designed layouts can lead to excessive memory usage, causing slow UI response. The Android SDK provides tools to help you analyze performance issues in your layouts. Combining tools with the practices discussed in this section can achieve a smooth scrolling user interface with minimal memory usage.
Use Hierarchy Viewer
The Hierarchy Viewer tool is located in < SDK > oolsolder, and this tool can analyze unreasonable layouts and areas that can be optimized. For specific usage, refer to examples introduced in previous articles.
In most cases, the significant difference in layout rendering time is due to the use of layout_weight in LinearLayout. This will increase measurement time. You should carefully consider whether it is necessary to use layout weight.
Use Lint
Use Lint — to see which areas of your view hierarchy can be optimized.
-
Use compound drawables – A LinearLayout containing an ImageView and a TextView can be treated as a compound drawable.
-
Use merge root framework – If a FrameLayout is purely a layout root element (without background, margins, etc.), we can use the merge tag as the root tag.
-
Useless branches – If a layout has no child components, it can be removed, thus improving efficiency.
-
Useless parent controls – If a layout only has child controls, has no sibling controls, is not a ScrollView or root node, and has no background set, we can remove this parent control and elevate the child control to the parent control.
-
Deep layouts – Try to reduce nested levels and consider using more peer components like RelativeLayout or GridLayout to improve layout performance. The default maximum depth is 10.
Other Layout Points
-
Re-using Layouts with <include/>
-
Use the <merge>
-
Loading Views on Demand
<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay ….
/>
Optimize App Memory
To allow the garbage collector to reclaim your system’s memory, you should avoid causing memory leaks (usually caused by global members holding object references) and release referenced objects at appropriate times (such as during lifecycle callbacks, which will be discussed further in later sections).
Be Cautious with Services
-
Services must be stopped after completing background tasks; note: do not let a service continue running after its tasks are completed.
-
Use IntentService
IntentService differs from a regular Service in that:
-
The submitted tasks will be posted to run on a child thread.
-
When the background task completes, the system will stop the IntentService.
onHandleIntent(Intent intent)
When a service does not need to run in the background but continues to do so, it is a significant memory management error. Therefore, be cautious with services, and remember to stop them when the background tasks are completed. If not, due to RAM limitations, your app will become very sluggish, and users will notice erratic app behavior, ultimately leading to uninstallation.
Release Memory When Your User Interface Becomes Hidden
For example, perform resource release work (such as network connections, unregistering broadcasts, etc.) in onStop().
Use Optimized Collection Containers
For example: SparseArray, SparseBooleanArray, LongSparseArray ….
Avoid Using Enums
Compared to static constants, enums have more than twice the memory overhead and should be strictly avoided in Android.
Avoid Using Dependency Injection Frameworks
Use ProGuard to Eliminate Unused Code
Use zipalign to Optimize and Align Your APK
-
Optimization avoids using more memory; resources will no longer be mapped into memory from the APK.
Note: Google Play Store does not accept APKs that have not been zipaligned.
Use MAT to Analyze and Optimize Memory
-
I/O must be closed after use, databases and Cursors must be closed after use.
-
Use finalize() + MAT to analyze memory leaks.
Android optimization mainly involves memory, layout, and performance optimization. This article summarizes some knowledge points about optimization in Android. In fact, many of these knowledge points can be elaborated upon. If anyone is interested in a specific aspect, please leave us a message. In subsequent articles, we will have dedicated discussions.
Did you gain anything from reading this article? Please share it with more people.
For more learning materials, click the “Read Original” below.
Java and Android Architecture
Welcome to follow us, let’s discuss technology together. Scan and long-press the QR code below to quickly follow us. Or search for the WeChat public account: JANiubility.
Public Account:JANiubility