1. 程式人生 > >Android 之 效能優化

Android 之 效能優化

眾所周知,android裝置作為一種移動裝置,不管是cpu還是記憶體都無法跟pc裝置相提並論。這就意味著我們不能無限制地使用記憶體和cpu的資源,過多地使用記憶體會導致oom,過多地使用cpu資源,做大量的耗時任務,會導致手機變得異常卡頓,甚至無法響應出現ANR。所以我們在平常做開發時,一定要注意效能優化的問題,養成良好的編碼習慣才會成為優秀的程式設計師。

話不多說,我將介紹以下幾種優化方案

目錄

(1)佈局優化

(2)繪製優化

(3)記憶體洩露優化

(4)執行緒優化


(1)佈局優化

    佈局優化的核心思想減少佈局的層級,這樣會減少android繪製時的工作量。

    如何進行佈局優化?

 (a)如果佈局既可以使用Linearlayout和Relativelayout,建議選擇Linearlayout;

          如果我們要實現巢狀佈局時,建議採用Relativelayout。

 (b)採用標籤來優化佈局

    <include>標籤

   作用 用於佈局的重用。

   應用場景:下圖是我們開發中經常使用到的一個頂部標題欄(當然我已經對此進行過了封裝)

     

     我們很多頁面都需使用到,所以這裡要進行佈局的重用,這樣不僅減少了大量的程式碼量,同時也提高了繪製的效能。

     使用如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity.ChangePwdActivity">

    <include layout="@layout/title_layout"/>

</RelativeLayout>

   <merge>標籤

    <merge/>多用於替換FrameLayout或者當一個佈局包含另一個時,<merge/>標籤消除檢視層次結構中多餘的檢視組。例如你        的主佈局檔案是垂直佈局,include引入了一個垂直佈局,這時如果include佈局使用的LinearLayout就沒意義了,而且會減慢ui      的繪製速度。

<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>

   <ViewStub>標籤

    ViewStub的意義在於按需載入所需的佈局檔案,例項開發中,比如網路異常時的介面,這個時候沒有必須在整個介面初始化        的時候載入進來,通過ViewStub可以做到使用的時候再載入進來,提高了程式初始化的效能。

    使用如下:

 <ViewStub
        android:id="@+id/stub"
        android:inflatedId="@+id/stub_layout"
        android:layout="@layout/title_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

  android:inflateId:重寫ViewStub的父佈局控制元件的Id;android:layout:設定ViewStub被inflate的佈局。

  載入如下:

    //當你想載入佈局時,可以使用下面其中一種方法:
    ((ViewStub) findViewById(R.id.stub)).setVisibility(View.VISIBLE);  
    // or  
    View importStub = ((ViewStub) findViewById(R.id.stub)).inflate(); 

   目前ViewStub不支援<merge>標籤,且ViewStub的inflate只能執行一次,顯示了之後,就不能再使用ViewStub控制它了。

(2)繪製優化

   繪製優化的核心思想減少view在ondraw方法裡執行大量的操作。

   繪製優化記住兩點:onDraw方法裡不要建立新的區域性物件,onDraw方法裡不要做耗時操作,也不要執行成千上萬次的迴圈。因為

   ondraw方法都是頻繁呼叫的,會佔用系統很大的一部分記憶體,所以在我們實現自定義view的時候,一定要仔細檢查onDraw()裡的程式碼。

(3)記憶體洩露優化

   首先記憶體洩露是什麼?簡而言之:記憶體洩露就是長生命週期的物件持有短生命週期的引用,gc不能及時回收。

   這裡推薦一篇文章 java記憶體洩露

   這裡我就只介紹一種 靜態變數導致記憶體洩露的問題

   下面的程式碼將導致activity不能正常銷燬,因為mcontent應用了它,雖說這種錯誤大家都不會犯,但我們還是得重視。

public class Main2Activity extends AppCompatActivity {
    private static Context mcontext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mcontext = this;
    }
}

(4)執行緒優化

   作為初級程式設計師,比如說我,之前在做主執行緒裡做耗時操作時基本都是建立一個thread物件,這種確實簡單,但也是有弊端的,我們不 

   可能無限制地建立執行緒,這樣可能會將系統的資源耗盡,嚴重的話會造成系統崩潰。

   所以java引入了執行緒池的概念,執行緒池的好處:

   執行緒池內可以重用執行緒,避免執行緒的建立和銷燬所帶來的效能開銷;

   執行緒池可以控制併發數,避免大量的執行緒因搶佔系統資源導致阻塞現象的發生。

   具體執行緒池的講解我不過多介紹,自行Google,有些部落格上介紹的非常詳細。

   總結

    關於Android的效能優化我今天只能介紹到這裡,更多的優化方式還是需要大家今後在學習中探索。

    本文參考:《android開發藝術探索》