天天看點

Android的UI調優

對于一個App的UI而言,在流暢性上的改進目标其實就是降低螢幕繪制的延遲,建立流暢和穩定的幀率以避免卡頓。

      在理想情況下,全部的測量、布局和繪制的時間最好在16ms以内,這樣才能保證螢幕運作的順暢性。而如何對螢幕渲染和UI性能進行評估和分析呢,在Android SDK中內建了一些工具用來政策APP的渲染性能問題。

一、視圖的層級分析:

         對于每一個視圖而言,都需要經過三個步驟:測量、布局和渲染。而App如何繪制視圖,它需要從頂部節點開始測量,沿着布局樹逐個渲染,視圖樹的層級越多,嵌套測量的次數越多,測量的時間也會越長。而一旦測量完畢就會進行布局,每個視圖都會對自己的子視圖進行布局,子視圖布局完畢後回到父視圖,然後再到根視圖,布局完成後,每個視圖都會被繪制在螢幕上。

         顯然,App的視圖越多,層級越深就需要越長的時間測量、布局和繪制,為了減少這些時間,需要盡可能保持視圖層級的扁平化并删除所有沒有必要渲染的視圖。

         雖然在XML布局檔案中可以檢視布局的節點視圖,單很難找到多餘的視圖,為了找到這些多餘的視圖,可以利用Android Studio中的Hierarchy Viewer工具來分析Android App中的視圖。

         Hierarchy Viewer(層次結構檢視器)能夠便捷地以可視化方式檢視各種視圖嵌套關系,可用于研究XML視圖結構。(需要一個運作Android App的裝置)

Android的UI調優

利用這個工具可以檢視我們的View的層次,進而借助它修改我們的布局。

一般的建議:

使用抽象布局标簽(include, viewstub, merge)主要是為了優化布局,去除不必要的嵌套和View節點。

視圖重用

多用于ListView和RecylerView等清單形式

使用include嵌套布局,實作布局的子產品化設計,這裡需要考慮到下面談到的merge标簽的使用。

<merge>标簽

在使用了include後可能導緻布局嵌套過多,多餘不必要的layout節點,進而導緻解析變慢,不必要的節點和嵌套可通過hierarchy viewer或設定->開發者選項->顯示布局邊界檢視。merge标簽在UI的結構優化中起着非常重要的作用,它可以删減多餘的層級,優化UI。 

merge多用于替換FrameLayout或者當一個布局包含另一個時,merge标簽消除視圖層次結構中多餘的視圖組。

merge标簽可用于兩種典型情況: 

a. 布局頂結點是FrameLayout且不需要設定background或padding等屬性,可以用merge代替,因為Activity内容視圖的parent view就是個FrameLayout,是以可以用merge消除隻剩一個。 

b. 某布局作為子布局被其他布局include時,使用merge當作該布局的頂節點,這樣在被引入時頂結點會自動被忽略,而将其子節點全部合并到主布局中。

<ViewStub>

viewstub标簽同include标簽一樣可以用來引入一個外部布局,不同的是,viewstub引入的布局預設不會擴張,即既不會占用顯示也不會占用位置,進而在解析layout時節省cpu和記憶體。 

viewstub常用來引入那些預設不會顯示,隻在特殊情況下顯示的布局,如進度布局、網絡失敗顯示的重新整理布局、資訊出錯出現的提示布局等。

比如說,假設network_error.xml為隻有在網絡錯誤時才需要顯示的布局,預設不會被解析。 

當我們要使用的時候,有兩種方法可以使用,效果是一樣的:

((ViewStub) findViewById(R.id.layout_error)).setVisibility(View.VISIBLE); 

// 或者

View importPanel = ((ViewStub) findViewById(R.id.layout_error)).inflate(); 

二、資源縮減

第一點提到的是将App的視圖結構變扁平,減少視圖的數量後,其實我們還可以嘗試減少每個視圖裡使用的資源數量。(如加載時引用一個資源,在運作時進行着色)

三.螢幕的過度繪制

         螢幕的過度繪制這個概念有點類似于PhotoShop中的圖層的概念,上面的圖層會覆寫住下面的圖層,而使得下面的圖層不可見。當Android系統繪制螢幕時,首先繪制父視圖而後是子視圖,子視圖位于其父視圖上。

         重繪螢幕的行為被稱為過度繪制,多次的螢幕繪制會增加延遲,并且可以導緻布局卡頓。

         既然過度繪制的影響那麼大,我們應該怎麼檢測呢?

         Android提供了一些很好的工具來檢測過度繪制,而一般采用的方式是在Debug GPU Overdraw菜單中選擇“Show Overdraw area”,(在本人手機中為開發者選項中的調試GPU過度繪制),選擇之後會在App的不同區域覆寫不同的顔色來表示過度繪制的次數。比較螢幕上的這些不同顔色,可以快速定位問題。

         白色:沒有過度繪制

藍色:1次過度繪制(螢幕繪制了2次)

綠色:2次過度繪制

淺紅色:3次過度繪制

深紅色:4次或更多次過度繪制

Android的UI調優

而另外一種檢視方法是借助于前面提到的Hierarchy Viewer工具,将view hierarchy儲存為Photoshop文檔,打開這些視圖後可以看到不同層次的過度繪制情況。

四、分析卡頓(政策GPU的渲染能力)

         在優化視圖的層次結構和過度繪制後,App還存在丢幀或者不流暢的情況,為了獲得獲得更加全面的卡頓檢測資訊,Android系統中有一個Profile GPU Rendering的開發者選項,它能夠檢測出每一幀在螢幕上用了多久,政策資料可以儲存到日志檔案中,或者在裝置上實時顯示。一般而言,在螢幕上直接展示GPU的渲染資料能夠更加直覺地看到。

Android的UI調優

在本人的手機中,在開發者選項中找到【GPU呈現模式分析】,選擇【在螢幕上顯示為條形圖】,然後打開一個手機QQ,就發現如下圖所示情況

Android的UI調優

需要關注的是底部的那一條水準綠線,它表示裝置渲染一幀要16ms,每一幀就是一個水準條,如果有很多幀超過了這條綠線就說明裝置出現了卡頓情況。

五、讓它看起來更快

         前面講到了如果通過測試發現問題優化布局使得UI繪制更加流暢,其實還有一個方法使得UI繪制更快:讓它看起來更快。

進度條

動畫

即時更新:指使用者更新了一個頁面後,頁面上的資料就會立刻發生變化,即使資料還沒有達到伺服器(這裡需要确定這些資料最終一定可以更新到伺服器)(離線上傳,離線發送網絡請求)

本文轉自 bxst 51CTO部落格,原文連結:http://blog.51cto.com/13013670/1943974