In the development process we often say performance optimization, but performance optimization is a relatively broad concept. Performance optimizations in Android development may include: Java code optimization, algorithmic optimization, sqlite optimization, layout optimization, and more. Then this blog will summarize and share the layout optimization in Android development.
Layout principles
In the Android UI layout process, by following some idiomatic and effective layout principles, we can create a highly efficient and reusable UI that generally includes the following points:
Use Relativelayout and linearlayout as much as possible, do not use absolute layout absolutelayout, in the same layout hierarchy, we recommend using LinearLayout instead of relativelayout, Because LinearLayout performance is slightly higher, but often relativelayout can be easily implemented linearlayout nesting to achieve the layout.
Extracting reusable components and using the include tag;
Use the viewstub tag to load some less commonly used layouts;
Use the Merge tab to reduce the nesting level of the layout;
Relativelayout VS LinearLayout
The first principle says that the layout level of the same situation linearlayout better than relativelayout, but often relativelayout can simply implement linearlayout nesting to achieve the layout. If you need to implement the following layout:
Use LinearLayout to implement the XML code as follows:
<linearlayout xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Fill_parent" android:layout_height="? Android:attr/listpreferreditemheight" android:padding="6dip"> <imageview android:id="@+id/icon" android:layout_width="Wrap_content" android:layout_height="Fill_parent" android:layout_marginright="6dip" android:src="@drawable/icon" /> <linearlayout android:orientation="Vertical" android:layout_width="0dip" android:layout_weight="1" android:layout_height="Fill_parent"> <textview android:layout_width="Fill_parent" android:layout_height="0dip" android:layout_weight="1" android:gravity="Center_vertical" android:text="My Application" /> <textview android:layout_width="Fill_parent" android:layout_height="0dip" android:layout_weight="1" android:singleline="true" android:ellipsize="Marquee" android:text="Simple Application This shows how to use Relativelayout" /> </LinearLayout></LinearLayout>
The implementation of the code with Relativelayout is as follows:
<relativelayout xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Fill_parent" android:layout_height="? Android:attr/listpreferreditemheight" android:padding="6dip"> <imageview android:id="@+id/icon" android:layout_width="Wrap_content" android:layout_height="Fill_parent" android:layout_alignparenttop="true" android:layout_alignparentbottom="true" android:layout_marginright="6dip" android:src="@drawable/icon" /> <textview android:id="@+id/secondline" android:layout_width="Fill_parent" android:layout_height="26dip" android:layout_torightof="@id/icon" android:layout_alignparentbottom="true" android:layout_alignparentright="true" android:singleline="true" android:ellipsize="Marquee" android:text="Simple Application This shows how to use Relativelayout" /> <textview android:layout_width="Fill_parent" android:layout_height="Wrap_content" android:layout_torightof="@id/icon" android:layout_alignparentright="true" android:layout_alignparenttop="true" android:layout_above="@id/secondline" android:layout_alignwithparentifmissing="true" android:gravity="Center_vertical" android:text="My Application" /></RelativeLayout>
Can be seen with relativelayout implementation, the layout level is significantly less, so most of the time preferred to recommend the use of relativelayout.
View Layout Hierarchy
How do I see the layout hierarchy? There are two ways: one is through the mobile developer options, 4.0 and above Android version can be set by the developer options, and display layout boundaries to open the page layout display, see if there are unnecessary nodes and nesting. The second is to take advantage of the SDK's own UI performance detection Tool, Hierarchyviewer. Go to the Tools folder under the SDK directory, find Hierarchyviewer and run (keep your emulator or the real machine running for analysis), and double-click the process represented by the app that we're showing. The next step is to enter the Hierarchyviewer interface, where we can clearly see the layout hierarchy of the running UI and the relationship between them. The approximate display is as follows:
With the layout diagram we can see that the root node Decorview contains a linearlayout, which is the layout parent that contains the entire screen of the activity layout and status bar, the LinearLayout has two child nodes, One is Framelayout, Framelayout is the activity layout of the default parent layout node, this node contains our own written XML layout, there is a child node is viewstub, about this node we will be detailed in the following.
Use of < include/>
In the actual development, we often encounter some common UI components, such as the navigation bar with the return button, if you set this part of the layout for each XML file, one is the duplication of the workload, and second, if there are changes, then each XML file has to be modified. Fortunately, Android provides us with an include tag, which, by definition, lets you extract these common components into an XML file, and then use the Include tag to import the shared layout, so that the two issues mentioned earlier are resolved. The following is an example of introducing another layout header.xml with include in one layout main.xml.
Header.xml file
<?xml version= "1.0" encoding= "Utf-8"?><relativelayout xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Match_parent" android:layout_height="Match_parent" > <button android:id="@+id/button" android:layout_width="Match_parent" android:layout_height="@dimen/dp_40" android:layout_above="@id/text"/> <textview android:id="@+id/text" android:layout_width="Match_parent" android:layout_height="@dimen/dp_40" android:layout_alignparentbottom="true" android:text="@string/app_name" /></RelativeLayout>
We then import this common layout through include in the layout XML that needs to introduce footer.
Main.xml file
<framelayout xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Match_parent" android:layout_height="Match_parent"> <textview android:layout_width="Match_parent" android:layout_height="Wrap_content" android:text="Hello World" /> <relativelayout android:layout_width="Match_parent" android:layout_height="Match_parent" android:layout_gravity="Center" > <include layout="@layout/header" /> </RelativeLayout></FrameLayout>
In this way, we can improve the production and reuse efficiency of the UI, as well as make the UI layout more structured and easy to maintain.
< the use of merge/>
The merge tag is a combination of UI layouts that can be used to reduce the nesting level of the UI layout. The Merge tab can be used in two typical cases:
The layout root node is framelayout and does not need to set properties such as background or padding, which can be replaced with merge because the parent view of the activity content layout is a framelayout. So you can use the merge to eliminate only one, which can be seen from it.
When a layout is used as a sub-layout by another layout include, use merge as the top node of the layout, so that the top nodes are automatically ignored when they are introduced, and all of their child nodes are merged into the main layout.
In the first case, the Main.xml layout can be optimized as follows:
<merge xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Match_parent" android:layout_height="Match_parent"> <framelayout android:layout_width="Match_parent" android:layout_height="Match_parent"> <textview android:layout_width="Match_parent" android:layout_height="Wrap_content" android:text="Hello World" /> <relativelayout android:layout_width="Match_parent" android:layout_height="Match_parent" android:layout_gravity="Center" > <include layout="@layout/header" /> </RelativeLayout> </FrameLayout></merge>
In the second case, the Header.xml layout can be optimized as follows:
<?xml version= "1.0" encoding= "Utf-8"?><merge xmlns:android="Http://schemas.android.com/apk/res/android" android:layout_width="Match_parent" android:layout_height="Match_parent" > <button android:id="@+id/button" android:layout_width="Match_parent" android:layout_height="@dimen/dp_40" android:layout_above="@id/text"/> <textview android:id="@+id/text" android:layout_width="Match_parent" android:layout_height="@dimen/dp_40" android:layout_alignparentbottom="true" android:text="@string/app_name" /> </merge>
This will not have redundant framelayout and relativelayout nodes.
Viewstub Label
The viewstub tag can be used to introduce an external layout as well as an include tag, but the layout introduced by Viewstub does not expand by default, which saves both the display and the location, saving CPU and memory when parsing layout. Viewstub is often used to introduce layouts that are not displayed by default, only in special cases, such as progress layouts, refresh layouts for network failures, prompt layouts for information errors, and so on.
We create a new XML file to display a network error when the prompt information error.xml:
<relativelayout xmlns:android="Http://schemas.android.com/apk/res/android" xmlns:tools="Http://schemas.android.com/tools" android:layout_width="Wrap_content" android:layout_height="Wrap_content" > <textview android:layout_width="Wrap_content" android:layout_height="Wrap_content" android:layout_centerinparent="true" android:background="@android: Color/white" android:padding="10dip" android:text="Message" android:textcolor="@android: Color/black" /></RelativeLayout>
Then add viewstub tags to the main.xml to introduce the above layout:
<merge xmlns:android="Http://schemas.android.com/apk/res/android" xmlns:tools="Http://schemas.android.com/tools" android:layout_width="Match_parent" android:background="@android: Color/darker_gray" android:layout_height="Match_parent" >...<viewstub android:id="@+id/error_layout" android:layout_width="Wrap_content" android:layout_height="Wrap_content" android:layout_gravity="Center" android:layout="@layout/error" /></merge>
In Java, find viewstub through (viewstub) Findviewbyid (ID), expand viewstub through Stub.inflate (), and then get the child view, as follows:
Private View Errorview; Private void ShowError() { // not repeated Infalte if (Errorview != NULL) { Errorview.setvisibility(View.VISIBLE); return; } viewstub stub = (viewstub)Findviewbyid(R.ID.Error_layout); Errorview = stub.Inflate();} Private void showcontent() { if (Errorview != NULL) { Errorview.setvisibility(View.GONE); }}
In the above ShowError () to expand the viewstub, and we have to save Errorview, so the next time we do not have to continue inflate.
Summarize
This blog does not detail the use of hierarchyviewer tools, I believe that if the layout of the principle of proficiency, the dependence on the tool greatly reduced, the development efficiency will be greatly improved. In addition to these layout principles, you also need to be familiar with the properties of various Android components, such as a layout, a picture and a text layout, the novice will often use a layout nested ImageView and TextView to do, But when we know that TextView has drawableleft, Drawableright and other properties, it is very fast and efficient to implement such a layout. In short, and learn and practice!
Android Layout optimization