Android中View繪製優化之一---- 優化佈局層次

譯序

最近一直在做鎖屏界面,之前也寫過關於鎖屏界面的一些簡單原理,未曾想自己真正去深入理解鎖屏時,才
發覺鎖屏框架真是又大又複雜,主要體現在如下兩個方面:

1、界面的組成以及更新機制;
2、對電源管理的控制,在鎖屏界面會禁用系統的電源管理,自己接管屏幕亮度的控制。

當然還有更多的邏輯細節處理,只能耐着性子去研究了。。

通過對本次鎖屏界面的處理,才發現自己對View繪製還是不熟透,很多東西也沒有去潛心研究,導致自己在
真正做項目時候才手忙腳亂的。因此,藉着這次機會,也把Android 4.0 developer這些先進的知識(山人一直
沉浸在Android 2.2中)給過了一下,真是妙處多多。

開頭: 爲了避免歧義,先將Android “Layout”一次的意思進行說明,主要有如下三個方面:
1、統稱,即如何擺放UI,UI呈現效果等;
2、佈局文件 ,即/res/layout/xxx.xml ;
3、佈局過程 ,Android繪製過程中的 layout過程;
4、一些佈局控件,例如LinearLayout、FrameLayout等 ;

正文

改善佈局效率(Layout Performace)

本文翻譯地址:http://developer.android.com/training/improving-layouts/index.html

佈局是Android應用程序重要的一部分,它與用戶體驗有着直接聯繫。如果一個佈局是糟糕的,它將產生一個
消耗內存與低效UI應用程序。 Android SDK 及它包含的工具都能幫助你定位在佈局過程中隱藏的問題,通過對
這些課程的學習,你能夠以很小的內存代價去實現流暢的平滑界面。

課程如下:

1 、優化佈局層次
同樣地,一個複雜的網頁會延長加載時間,你的佈局層次如果太複雜也能引發一些效率問題。本課程
告知你如何利用 SDK的工具去觀察你的佈局以及發現佈局過程的瓶頸問題。

2、使用標籤複用佈局文件
如果應用程序的UI在多處重複某些佈局結構,本課程向你展示如何創建高效、可重用的佈局結構,然後可以用合適的 UI佈局文件包含它們。

3、按需加載View視圖
除了簡單地在另外的佈局文件中包括一個佈局組件,你可能想在需要的時候纔將視圖顯現出來,有的時候
是在Activity運行之後。本課程告訴你如何改進佈局初始化行爲—- 按需加載佈局文件的某個視圖。

4、如何使ListView流暢滑動
如果你構建了一個ListView實例呈現那些包含複雜或者大容量數據的列表項,這可能會影響ListView的流暢
滑動。本課程提供了一些如何讓滑動過程更加流暢的建議。

譯一 :

優化佈局層次

本文地址:
http://developer.android.com/training/improving-layouts/optimizing-layout.html

一個通常的錯誤觀念就是使用基本的佈局結構(例如:LinearLayout、FrameLayout等)能夠在大多數情況下產生高效率 的佈局。 顯然,你的應用程序裏添加的每一個控件和每一個佈局都需要初始化、佈局(layout)、繪製 (drawing)。舉例來說:嵌入一個LinearLayout會產生一個太深的佈局層次。更嚴重的是,嵌入幾個使用 layout_weight屬性的LinearLayout 將會導致大量的開銷,因爲每個子視圖都需要被測量兩次。這是反覆解析佈局文件時重要的一點,例如在ListView或者GridView中使用時。

觀察你的佈局

Android SDK 工具箱包括一個稱作“ Hierarchy Viewer”的工具,它允許你去在你的應用程序運行時分析佈局。通過使用這個工具,能幫助你發現你的佈局效率上的瓶頸問題。

“ Hierarchy Viewer”工具允許你在已連接的設備或模擬器中選擇正在運行的進程,然後呈現出佈局層次樹(layout tree)。每個正方塊下的交通燈(見下圖) — 紅綠藍表現出了在測量(measure)、佈局(layout)、以及繪製(draw)過程中的效率值,這能幫助你定位潛在的問題。

假設ListView 中的一項Item 存在如下(見圖 1)佈局 :
這裏寫圖片描述

“Hierarchy Viewer”工具可以在 /tools路徑下找到。當打開它時,“ Hierarchy Viewer”工具顯示了所有可用的設備以及運行在這些設備上的進程。點擊”Load View Hierarchy”來顯示某個你選擇的組件的UI佈局層次。舉例來說,圖2展現了圖1的佈局層次樹。

這裏寫圖片描述
圖2:使用LinearLayout的佈局樹

在圖2中,你可以直觀看到這個三層的佈局結構是存在一些問題的。點擊項體現出了在每個測量(measure)、
佈局(layout)、以及繪製(draw)過程中的時間消耗(見圖3)。很明顯,該項(LinearLayout)花費了最長的時間去
測量、佈局、繪製,你應該花點精力去優化它們。
這裏寫圖片描述
圖3: 某個LinearLayout的繪製時間

完成該佈局文件渲染的時間分別爲:
測量過程:0.977ms
佈局過程: 0.167ms
繪製過程:2.717ms

修改佈局文件

由於上圖中佈局效率的低下是因爲一個內嵌的 LinearLayout控件,通過扁平化佈局文件—-讓佈局變得
更淺更寬,而不是變得更窄更深層次 ,這樣就能提升效率了。 一個RelativeLayout 作爲根節點也能提供如上
的佈局效果(即圖1)。 因此, 使用RelativeLayout 改變佈局的設計,你可以看到現在我們的佈局層次只有2層了。
新的佈局層次樹如下:

這裏寫圖片描述

現在,完成該佈局文件渲染的時間分別爲:
測量過程:0.977ms
佈局過程:0.167ms
繪製過程:2.717ms

也許它只是一點點微小的改進,但這次它會被多次調用,因爲是ListView會佈局所有的Item,累積起來,
改進後效果還是非常可觀地。

大部分的時間差異是由於使用了帶有layout_weight 屬性的LinearLayout ,它能減緩測量過程的速度。這僅僅
是一個例子,即每個佈局都應該合適地被使用以及你應該認真考慮是否有必要採用“layout_weight” 屬性。

使用Lint工具 (譯者注:ADT插件更新到最新的16.0後的工具)

關於Lint的使用更多請看:《Android Lint(官方代碼優化利器)》

一個好的實踐就是在你的佈局文件中使用Lint工具去尋求可能優化佈局層次的方法。Lint已經取代了Layoutopt
工具並且它提供了更強大的功能。一些Lint規則如下:

1、使用組合控件 — 包含了一個 ImageView 以及一個 TextView 控件的 LinearLayout 如果能夠作爲一個
組合控件將會被更有效的處理。
關於這點,更多請看: http://stackoverflow.com/questions/8318765/how-do-i-use-a-compound-drawable-instead-of-a-linearlayout-that-contains-an-imag

2、合併作爲根節點的幀佈局(Framelayout) —-如果一個幀佈局時佈局文件中的根節點,而且它沒有背景圖片或者padding等,更有效的方式是使用標籤替換該< Framelayout />標籤 。

3、無用的葉子節點—– 通常來說如果一個佈局控件沒有子視圖或者背景圖片,那麼該佈局控件時可以被移除
(由於它處於 invisible狀態)。

4、無用的父節點 —– 如果一個父視圖即有子視圖,但沒有兄弟視圖節點,該視圖不是ScrollView控件或者
根節點,並且它沒有背景圖片,也是可以被移除的,移除之後,該父視圖的所有子視圖都直接遷移至之前父視圖
的佈局層次。同樣能夠使解析佈局以及佈局層次更有效。

5、過深的佈局層次 —-內嵌過多的佈局總是低效率地。考慮使用一些扁平的佈局控件,例如 RelativeLayout、
GridLayout ,來改善佈局過程。默認最大的佈局深度爲10 。

當使用Eclipse環境開發時,Lint能夠自動解決一些問題,提供一些建議以及直接跳轉到出錯的代碼中去核查。
如果你沒有使用Eclipse,Lint也可以通過命令行的方式運行。

原文地址:http://blog.csdn.net/qinjuning/article/details/7944148

發佈了80 篇原創文章 · 獲贊 141 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章