Android 之 效能優化
眾所周知,android裝置作為一種移動裝置,不管是cpu還是記憶體都無法跟pc裝置相提並論。這就意味著我們不能無限制地使用記憶體和cpu的資源,過多地使用記憶體會導致oom,過多地使用cpu資源,做大量的耗時任務,會導致手機變得異常卡頓,甚至無法響應出現ANR。所以我們在平常做開發時,一定要注意效能優化的問題,養成良好的編碼習慣才會成為優秀的程式設計師。
話不多說,我將介紹以下幾種優化方案
目錄
(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開發藝術探索》