【學習筆記】Android性能優化----->佈局優化

1.AndroidUI渲染機制

人眼所感受的流暢畫面,須要畫面的幀數達到40幀每秒到60幀每秒

在Android中,系統經過VSYNC信號觸發對UI的渲染/重繪,其間隔時間是16ms,這個16ms其實就是1000ms中

顯示60幀畫面的單位時間,即1000/60

若是系統每次渲染的時間都保持在16ms以內,那咱們看見的UI界面將是很是流暢的

但這也就須要將全部程序的邏輯都保證在16ms以內

若是不能在16ms內完成繪製,那麼就會形成丟幀現象,即當前該重繪的幀被未完成的邏輯阻塞

例如一次繪製任務耗時20ms,那麼在16ms系統發出VSYNC信號時就沒法繪製,該幀就被丟棄,等待下次信號纔開始繪製,

致使16*2ms內都顯示同一幀畫面,這就是畫面卡頓的緣由


Android系統提供了檢測UI渲染時間的工具,打開「開發者選項」,選擇「Profile GPU Rendering」,
並選中「On screen as bars」的選項,這時候在屏幕上將顯示一些條形圖。


每一條柱狀線包含三部分:藍色表明測量繪製Display List的時間,紅色表明OpenGL渲染Display List所須要的時間,
黃色表明CPU等待GPU處理的時間。
中間的綠色橫線表明VSYNC時間16ms,須要儘可能將全部條形圖都控制在這條綠色之下。


2.避免Overdraw


Overdraw,過分繪製會浪費不少的CPU/GPU資源

例如系統默認會繪製Activity的背景
而若是再給佈局繪製了重疊的背景,那麼默認Activity的背景就屬於無效的過分繪製-Overdraw.


Android系統在開發者選項中提供了這樣一個檢測工具-"Enable GPU Overdraw".激活後,能夠經過界面上的顏色來判斷Overdraw的次數。

儘可能增大藍色區域,減小紅色區域。


3.優化佈局層級

在Android中,系統對View進行測量/佈局和繪製時,都是經過對View數的遍從來進行操做的。

若是一個View樹的高度過高,就會嚴重影響測量/佈局和繪製的速度,所以優化佈局的第一個方法就是下降View樹的高度。


Google在其API文檔中建議View樹的高度不宜超過10層。


在早期的Android版本中,Google使用LinearLayout做爲默認建立的XML文件的根佈局。

而如今的版本的Android中,Google已經使用RelativeLayout來替代LinearLayout做爲默認的根佈局。

其緣由就是經過扁平的RelativeLayout來下降經過LinearLayout嵌套所產生布局樹的高度,從而提升UI渲染的效率。 java

實際使用時,若是佈局中既可使用LinearLayout也可使用RelativeLayout,那麼就採用LinearLayout,由於RelativeLayout佈局過程須要花費更多的CPU時間。 android

若是須要經過嵌套的方式來完成佈局,這種狀況下仍是建議採用RelativeLayout。 工具

由於ViewGroup的嵌套就至關於增長了佈局的層級,會下降程序的性能。 佈局



4.避免嵌套過多無用佈局

嵌套的佈局會讓View樹的高度變得愈來愈高,


選擇不一樣的Layout組件,從而避免經過某一種Layout組件來實現功能的侷限性,從而形成嵌套過多的狀況發生。


4.1.使用<include>標籤重用Layout


4.2.使用<ViewStub>實現View的延遲加載
<ViewStub>也能夠引用並實現延遲加載。 性能

<ViewStub>是一個很是輕量級的組建,它不只不可視,並且大小爲0. 優化

能夠經過setVisibility()方法來顯示 spa

能夠經過ViewStub的inflate()方法來顯示這個View code

經過inflate()方法能夠返回引用的佈局,從而能夠再經過View.findViewById()方法來找到對應的控件。 資源

代碼: 開發


ViewStub mViewStub = (ViewStub)findViewById(R.id.mViewStub);

//                mViewStub.setVisibility(View.VISIBLE);
                View view = mViewStub.inflate();
                TextView tv_stub = (TextView)findViewById(R.id.tv_stub);
                tv_stub.setText("ViewStub");



無論使用哪一種方式,一旦<ViewStub>被設置爲可見或是inflate了,<ViewStub>就不存在,取而代之的是被inflate的Layout,

並將這個Layout的ID從新設置爲<ViewStub>中經過android:inflatedId屬性所指定的ID,

這也是爲何兩次調用inflate方法會報錯的緣由。

相關文章
相關標籤/搜索