Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android性能優化-布局優化

Android性能優化-布局優化

編輯:關於Android編程

在上一篇博客中,我和大家一起探討了在Android中對SQLite數據庫的操作優化細節。

今天,我們繼續Android性能優化系列 - 布局優化。在Android中,UI布局作為展示性的標志,顯示的速度直接體現了一個App對於客戶直觀的影響。一個好的App,在布局和UI上肯定有比較好的性能優化,所以布局優化成為了Android性能優化的有一個重點。

Android中關於布局優化,系統為我們提供了幾個抽象的標簽:

(1)include

(2)viewstub

(3)merge

 

下面,我們就來一一介紹三個標簽的作用和使用方式。

 

1> include

 

顧名思義,include標簽可以讓我們復用包含一個layout布局。例如,我們App在大部分情景下都是這樣的設計:topbar -> content -> footbar。

那麼,很多界面都是這樣的布局,我們就可以抽取出topbar和footbar作為公共布局,使用include就可以復用該布局,下面看代碼:

 

這是一個頭布局:layout_topbar.xml
 

<!--?xml version="1.0" encoding="utf-8"?-->
<linearlayout android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android">
    <relativelayout android:id="@+id/rl_root_title_base" android:layout_height="46dp" android:layout_width="match_parent">
        <textview android:gravity="center_vertical" android:id="@+id/tv_left_title" android:layout_centervertical="true" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_width="wrap_content" android:textcolor="#80C469">
        <textview android:ellipsize="end" android:id="@+id/tv_topic_title" android:layout_centerinparent="true" android:layout_height="wrap_content" android:layout_width="wrap_content" android:maxlength="10" android:singleline="true" android:textcolor="@color/cl_font_46" android:textsize="18dp">
        <textview android:gravity="center" android:id="@+id/tv_right_first_title" android:layout_alignparentright="true" android:layout_centervertical="true" android:layout_height="wrap_content" android:layout_marginright="10dp" android:layout_width="wrap_content" android:minheight="30dp" android:minwidth="30dp" android:textcolor="@color/cl_80c469" android:textsize="16dp">
                
        <textview android:gravity="center" android:id="@+id/tv_right_second_title" android:layout_centervertical="true" android:layout_height="wrap_content" android:layout_marginright="10dp" android:layout_toleftof="@id/tv_right_first_title" android:layout_width="wrap_content" android:minheight="30dp" android:minwidth="30dp" android:textcolor="#80C469">
    </textview></textview></textview></textview></relativelayout>
   <view android:background="@color/cl_font_ea" android:id="@+id/line_root_base" android:layout_height="0.5dp" android:layout_width="match_parent">
</view></linearlayout>

main.xml

<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
    <include layout="@layout/layout_top">
</include></linearlayout>

上面代碼中我們使用include的屬性layout來重用topbar布局。include還可以指定layout_width和layout_height以及id。如果指定了id屬性,則被包含的根布局id將會失效,此id將會被覆蓋。

2> viewstub

viewstub標簽和include標簽很相似,都是使用layout屬性來加載一個布局。不同之處是include標簽用來重用布局,該布局會在App啟動加載時被加載進內存。而viewstub標簽所引用的布局是不會被加載出來的,只有當你在某個時間需要使用時才會被加載出來,從而在解析layout時節省了cpu加載時間和內存的占用。

使用也非常簡單,看下面代碼:

 

<linearlayout android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
    <viewstub android:id="@+id/vstub_network_error" android:layout="@layout/layout_network_error" android:layout_height="match_parent" android:layout_width="match_parent">
</viewstub></linearlayout>

 

在布局代碼中,我們使用ViewStub的layout來加載一個布局。

 

private void showEmptyView() {

    if(ValidateUtils.isNullObj(viewNetWorkError)){

        ViewStub mViewStub = (ViewStub) findViewById(R.id.vstub_network_error);
        viewNetWorkError = mViewStub.inflate();
    } else {

        viewNetWorkError.setVisibility(View.VISIBLE);
    }
}
private void showCourseContent(Course course) {
    if(ValidateUtils.isNotNullObj(viewNetWorkError)) {
        viewNetWorkError.setVisibility(View.GONE);
    }
}

 

我們在代碼中通過findViewById來獲取ViewStub,然後調用其inflate方法就可以獲取到layout的view。

ViewStub的使用場景很廣泛:例如顯示加載失敗的界面,進度布局顯示,信息出錯提示等等。

 

3> merge

 

merge標簽用來取消layout的層級的顯示。大家都知道,Android頂級布局DecorView的根布局是讓FrameLayout。此時在我們的布局中如果我們使用FrameLayout,就會造成布局節點的層級疊加重復繪制。Android為我們提供了一個叫做hierarchy viewer來查看布局節點信息。該工具在sdk/tools目錄下。

要注意的一點是,merge標簽必須作為布局的根標簽,即不能嵌套在其他布局中。

使用很簡單,就不貼代碼了。

 

介紹完了以上3個抽象標簽的使用方式,想必大家都知道該如何去應用在自己的布局中來優化布局,下面還有幾點同時也需要大家去關注一下:

 

(1)inflate:大家都知道,inflate用來在代碼中加載一個現有的布局。例如我們可以使用LayoutInflater.from().inflate()來發加載,同時也可以在Activity中使用getLayoutInflater().inflate()來加載一個布局。但是每次使用inflate去加載布局是有時間和內存消耗的。所以我們要利用復用View來減少不必要的重復inflate。例如上面我們在介紹ViewStub的時候會去inflate。此時我們就可以將該View當做全局變量。下次只需要判斷下是否為null,就可以去重復使用,而不必每次都inflate加載了。

 

(2)ListView Adapter的getView方法:在該方法中我們都會去inflate一個布局,然後設置一些數據,最後return該View。ListView在每一個Item被渲染加載時都回去重復調用getView。並且ListView的convertView是可以重復利用的,所以我們可以利用ViewHolder的原理來復用convertView,而不必每次都inflate。

 

(3)使用SurfaceView和TextureView:SurfaceView和TextureView不會占用UI Thread來加載渲染視圖,他們都會開啟一個線程來異步進行加載。所以可以使用他們來優化加載速度及顯示效果。

 

(4)盡量為所有分辨率創建資源:減少不必要的硬件縮放,這樣會降低UI的繪制速度和占用大量的內存消耗。

 

注意:之前看到網上很多朋友說將View的可見性設置為gone。該View同樣不會被加載到內存。其實這種說法是錯誤的。從Android源碼可以知道,即使將View的visiablity設置為gone,View同樣會被加載的內存資源當中。即只有只有ViewStub加載的layout在App啟動後才不會被加載到內存資源。

好了,關於布局優化的內容就介紹到這裡了。更多的東西還需要大家去嘗試一下。下一篇我將和大家分享Android性能優化 一 數據優化

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved