Layout is a key part of the Android app that directly affects the user experience. If the implementation is not good, your Layout will cause the program to be very memory-intensive and the UI to run slowly. The Android SDK comes with tools to help you find Layout performance issues.
Topic One: Optimizing the layout hierarchy
A common misconception is that using the most basic layout structure can improve the performance of layout. However, because each component and layout of the program needs to be initialized, laid out, and drawn, the initialization, layout, and drawing operations are more time-consuming if the layout nesting causes the hierarchy to be too deep. For example, using nested linearlayout may cause the hierarchy of view to be too deep, and the computation of linearlayout nested with the Layout_weight parameter is particularly large because each child element needs to be measured two times. This is especially important for layout that requires multiple repetitions of inflate, such as when nested in a ListView or GridView.
In this lesson you'll learn to use Hierarchy Viewer and layoutopt to examine and optimize your layout. Use two tools: Hierarchy Viewer and Layoutopt.
How do you look at the layout of your design?
The Android SDK Toolkit has a tool called Hierarchy Viewer that analyzes Layout while the program is running. You can use this tool to find the performance bottleneck of Layout.
The Hierarchy Viewer will let you select a running process on the device or emulator and then display the tree structure of its Layout. The traffic lights on each block represent its performance in measurement, layout, and painting, helping you find the bottleneck. For example, the layout of a list item in a ListView. In the list item, put a small bitmap on the left and two stacked text on the right. such as the need to be multiple inflate Layout, optimize them will have a multiplier effect.
The Hierarchyviewer tool is available in <sdk>/tools/. Click Load View Hierarchy to view the layout Hierarchy of the selected component.
Find UI performance bottlenecks, how do I fix layout?
The above layout is too slow due to the nested linearlayout, and the possible solution is to flatten the layout hierarchy-lighter and wider, rather than narrow and deep. Relativealayout can be used as a root node to achieve the goal. So, when you switch to a relativelayout-based design, your Layout becomes two layers. The new layout changes to the following form:
It may seem like a small improvement, but because it works for every item in the list, it doubles the time. The main difference in this time is due to the use of layout_weight in LinearLayout because it slows down the "measurement" speed. This is just an example of using various Layout correctly, and it is necessary to be cautious when you use Layout_weight.
How do I use the lint tool to aid detection?
It is a good practice to run the Lint tool to check the possible optimization methods of Layout. Lint has replaced the Layoutopt tool, which has more powerful features.
How do I start lint from eclipse? The following methods are available:
The following detection rules are included in the lint:
Using compound drawable-to replace a ImageView with TextView and linearlayout with a compound drawable is more efficient.
Merge root frame-If framelayout is the root node of Layout and does not use padding or backgrounds, then replacing them with the merge tag is a little more efficient.
Useless child nodes-a Layout with no child nodes or backgrounds should be removed to get a flatter level.
Useless parent node-if a node does not have a sibling node, and it is not a ScrollView or root node, and there is no background, such nodes should be replaced directly by the quilt node to obtain a flatter hierarchy.
Too deep layout-layout nesting levels are too deep to have a significant impact on performance. Try using more flat Layout, such as Relativelayout or GridLayout, to improve performance. Generally no more than 10 storeys.
Topic Two: Reusing layouts with <include> tags
While Android offers a lot of small reusable interactions, you may still need to reuse more complex components, which might be used for Layout. To efficiently reuse the entire layout, you can use the <include/> and <merge/> tags to embed other layout into the current layout.
Reusing layout is powerful, allowing you to create complex reusable layout. For example, a yes/no button panel, or a custom progress bar with text. This also means that any element that recurs in multiple layout can be extracted, managed separately, and added to layout. So, while you can add a custom View to implement a separate UI component, you can easily reuse a Layout file directly.
How can I create a reusable layout?
If you already know the layout you need to reuse, create a new XML file and define layout. For example, the following is a Layout from G-kenya Codelab that defines a title bar (Titlebar.xml) that needs to be added to each Activity:
<framelayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "Match_ Parent " android:layout_height=" wrap_content " android:background=" @color/titlebar_bg "> < ImageView android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:src= "@ Drawable/gafricalogo "/></framelayout>
Where: The view type of the root node is the layout you want to add to the entry.
How to add to the specified layout, using the <include> tag
Using the <include> tab, you can add reusable components to Layout. For example, here is a Layout from G-kenya Codelab that needs to include the title bar above:
<linearlayout xmlns:android= "http://schemas.android.com/apk/res/android" android:orientation= "vertical" android:layout_width= "match_parent" android:layout_height= "match_parent" android:background= "@ COLOR/APP_BG " android:gravity=" Center_horizontal "> <include layout=" @layout/titlebar "/> <textview android:layout_width= "match_parent" android:layout_height= "wrap_content" android:text= "@ String/hello " android:padding=" 10DP "/> ...</linearlayout>
You can also overwrite all layout parameters (any android:layout_* attribute) of the added layout by declaring them in <include/>. Like what:
<include android:id= "@+id/news_title" android:layout_width= "match_parent" android:layout_height= " Match_parent " layout=" @layout/title "/>
It must be noted, however, that if you want to overwrite the attributes that are added to layout, you must first overwrite their layout_width and Layout_height properties.
Another way: Use <merge> tags
The <merge/> tag removes redundant viewgroup in the UI hierarchy when you nest Layout. For example, if you have a layout that is a vertical linearlayout that contains two consecutive view that can be reused in another layout, then you would do a linearlayout to include the two view for reuse. However, when using one linearlayout as the root node of another linearlayout, this nesting linearlayout does not make sense except to slow down your UI performance.
To avoid this situation, you can use the <merge> element instead of the root node of the reusable layout.
<merge xmlns:android= "Http://schemas.android.com/apk/res/android" > <button android:layout_ Width= "Fill_parent" android:layout_height= "wrap_content" android:text= "@string/add"/> < Button android:layout_width= "fill_parent" android:layout_height= "wrap_content" android:text= "@ String/delete "/></merge>
Now, when you want to include this layout in another layout (and use the <include/> tag), the system ignores the <merge> tag and puts two buttons directly into layout <INCLUDE&G T Location.
Topic Three: Loading layouts on demand
Topic Four: Optimizing the sliding performance of the ListView
The key to keeping the program flowing is to keep the main thread (UI thread) from doing a lot of arithmetic. You want to make sure that you perform disk read-write, network read-write, or SQL operations on other threads. To test the status of your app, you can enable Strictmode.
Use loads to load data
Using A background thread ("Worker thread") removes strain from the main thread so it can focus on drawing the UI. In many cases, using Asynctask provides a simple-to-perform your work outside the main thread. The UI thread only does the layout drawing, and the worker thread runs the background task.
Using a asynctask to load the slow images in a background threadnew asynctask<viewholder, Void, bitmap> () { Private Viewholder V; @Override protected Bitmap doinbackground (Viewholder ... params) { v = params[0]; return Mfakeimageloader.getimage (); } @Override protected void OnPostExecute (Bitmap result) { super.onpostexecute (result); if (v.position = = position) { //If this item hasn ' t been recycled already, hide the //progress and set and Sho W The image v.progress.setvisibility (view.gone); V.icon.setvisibility (view.visible); V.icon.setimagebitmap (result);}} . Execute (Holder);
This behavior is global, which means you don't have to think about what you define as a thread pool. Starting with Android 3.0 (API level 11), Asynctask has a new feature, which is that it can run on multiple CPU cores. You can call Executeonexecutor () instead of execute (), which can trigger multiple tasks at the same time based on the number of cores in the CPU.
Fill in a View object with Viewholder
Your code may often use Findviewbyid () when the ListView is sliding, which can degrade performance. Even if Adapter returns a view of the inflate that was used for recycling, you still need to look at the element and update it. One way to avoid frequent calls to Findviewbyid () is to use the Viewholder (view placeholder) design pattern.
A Viewholder object stores each view under his tag. This way you don't have to find this element frequently. First, you need to create a class to store the view you will use. Like what:
Static class Viewholder { TextView text; TextView timestamp; ImageView icon; ProgressBar progress; int position;}
Generate a Viewholder instance in the layout class:
Viewholder holder = new Viewholder (); Holder.icon = (ImageView) Convertview.findviewbyid (r.id.listitem_image); Holder.text = (TextView) Convertview.findviewbyid (r.id.listitem_text); holder.timestamp = (TextView) Convertview.findviewbyid (r.id.listitem_timestamp); holder.progress = (ProgressBar) Convertview.findviewbyid ( R.id.progress_spinner); Convertview.settag (holder);
This allows you to easily get each view, rather than using Findviewbyid () to constantly find sub-views, saving valuable computing time.
How do I improve the performance of layout in Android?