佈局效能優化:安卓開發者不可錯過的效能優化技巧

語言: CN / TW / HK

theme: fancy

今天總結一下佈局的效能優化,這是一個系列,上一篇是# 記憶體洩漏大集結:安卓開發者不可錯過的效能優化技巧 也可以看效能優化專欄裡的記錄,都是非常好的開發經驗。

當我們開發Android應用時,佈局效能優化是一個必不可少的過程。一個高效的佈局能夠提高使用者體驗,使應用更加流暢、響應更加迅速,而低效的佈局則會導致應用的執行變得緩慢,甚至出現卡頓、崩潰等問題,影響使用者體驗。在開發中,佈局優化不僅需要考慮到UI設計的美觀性和易用性,還需要關注佈局的效能,避免出現因檢視過多、巢狀過深、圖片過大等問題導致的效能瓶頸。通過對佈局進行優化,可以顯著提高應用的效能和使用者體驗,減少應用的CPU和記憶體佔用,加快應用的啟動和響應速度,降低應用的耗電量,從而提高應用的穩定性和可靠性。

佈局效能優化對於提高Android應用的質量和競爭力是至關重要的。在實際開發中,我們需要根據具體的業務場景和設計要求,結合佈局優化的最佳實踐,逐步提升應用的佈局效能,為使用者帶來更好的體驗。

佈局為什麼會有效能問題呢

那需要了解一下Android View的渲染機制,Android渲染機制是指Android系統中用於顯示介面的工作流程。它包括檢視樹的構建、測量、佈局和繪製四個過程。

他們的大致流程是 mermaid graph TD 構建檢視樹 --> 測量 --> 佈局 --> 繪製

  1. 構建檢視樹(View Hierarchy):在應用啟動時,Android系統會根據佈局檔案中定義的View、ViewGroup和其他元件建立一個檢視樹。檢視樹是根據xml進行解析的。
  2. 測量(Measure):在測量過程中,系統會遍歷檢視樹,並計算每個檢視的大小和位置
  3. 佈局(Layout):在佈局過程中,系統會根據檢視樹中每個檢視的測量結果,確定每個檢視的大小和位置,並將其放置在正確的位置上
  4. 繪製(Draw):在繪製過程中,系統會遍歷檢視樹,並將每個檢視繪製到螢幕上

在這幾個過程中,佈局過程是比較耗費時間的,並且耗時與檢視樹的複雜程度成正比。

複雜的佈局指的是樹關係的複雜,而不是元素的複雜。

不一樣的角度

從系統角度分析,Android系統的UI介面是基於檢視層次結構(View Hierarchy)構建的,每個UI元素都是View或ViewGroup物件的例項,這些物件按照它們在介面中出現的順序排列,構成了一個檢視層次結構。在這個結構中,每個UI元素都有自己的父元素和子元素,因此構成了一個樹形結構。這個樹形結構的根節點是一個ViewGroup物件,它是整個檢視層次結構的根。

當用戶進行互動操作時,Android系統需要對檢視層次結構進行更新,例如重新佈局、重繪等操作,這些操作會消耗大量的CPU和記憶體資源。因此,檢視層次結構的構建對應用程式的效能和響應速度至關重要。

常見佈局解析,用對了,你的效能問題會減少很多

我們從開始學習Android就知道五大布局是Android的佈局基礎,大家還記得他們的優缺點嗎?之所以有五大布局,就是因為他們使用場景各不相同,然而有時候寫法就是上來就相對,別的不考慮,這正確嗎?

這是一個對比表格,加顏色的,年齡小的程式設計師可能都不知道。

image.png

通過這個對比,你會發現,每一個佈局都有它的用途,要是用對了,在效能方面都有提升。也不是說用約束佈局一擼到底,在有些專場的場景中,對應的佈局更加優於約束佈局。

回顧完之後,我們看看開發中還有哪些影響效能的寫法。

常見的開發中有損佈局效能的操作方式

巢狀層數過多

當一個佈局容器包含多個子佈局容器時,會導致檢視層次結構的深度增加,從而增加了CPU和記憶體資源的消耗 ``` <LinearLayout

<RelativeLayout
</RelativeLayout>
<LinearLayout
    >

</LinearLayout>

```

記憶體使用過高

當一個佈局容器包含大量的子檢視時,會導致記憶體佔用過高,從而影響應用程式的效能

```

```

不合適的佈局容器

在佈局中選擇合適的佈局容器可以避免不必要的佈局操作和記憶體消耗(當需要顯示大量的資料列表時,使用ListView或RecyclerView等容器可以避免不必要的檢視更新和記憶體消耗)

過多的重繪操作

當一個佈局容器中包含多個檢視時,每次修改其中一個檢視的屬性,都會導致整個佈局容器的重繪操作

可以使用ViewStub元素來延遲載入複雜的檢視。

不合理的佈局屬性

在佈局中選擇合適的佈局屬性可以避免不必要的檢視更新和記憶體消耗

在使用RelativeLayout佈局容器時,它的測量和佈局都需要參考父、兄等原則,所以需要考慮到檢視的相對位置和大小,以避免不必要的佈局操作和記憶體消耗。

使用無效的佈局容器

在佈局中使用無效的佈局容器會增加不必要的佈局操作和記憶體消耗,影響應用程式的效能和響應速度

```

```

這種操作在開發中還是比較常見的,有時候為了給Text View或者ImageView 新增點選區域,外邊搞一個FragmeLayout。這種操作會導致記憶體消耗過高的。

常見的檢測佈局效能工具

  1. Hierarchy Viewer工具:Hierarchy Viewer工具可以幫助開發者分析應用程式的檢視層次結構,找出可能存在的效能問題。在Hierarchy Viewer中,可以檢視應用程式的檢視層次結構,以及每個檢視的繪製時間、測量時間和佈局時間等效能指標。
  2. TraceView工具:TraceView工具可以幫助開發者分析應用程式的效能問題,包括佈局效能問題。在TraceView中,可以檢視應用程式的方法呼叫鏈和執行時間等資訊,以及每個方法的CPU使用率、記憶體消耗等效能指標。
  3. UI效能分析器:Android Studio中內建了UI效能分析器,可以幫助開發者分析應用程式的UI效能問題,包括佈局效能問題。在UI效能分析器中,可以檢視應用程式的渲染時間、FPS、佈局時間等效能指標,並根據效能指標分析應用程式的效能問題。
  4. Monkey測試工具:Monkey測試工具可以幫助開發者測試應用程式的穩定性和效能問題,包括佈局效能問題。在Monkey測試中,可以模擬使用者隨機點選和滑動操作,以測試應用程式的穩定性和響應速度,同時可以通過TraceView等工具分析應用程式的效能問題。(提前做好監測的買點,trace收集,然後用monkey測試,最後分析trace)

總結

1.減少佈局層次

佈局層次越深,繪製所需的時間就越長,因此應該儘可能減少佈局層次。可以通過使用 ConstraintLayout 或者自定義 View 來減少佈局層次。

2.使用合適的佈局容器

應該選擇最適合當前佈局需求的佈局容器,避免使用過於複雜的佈局容器,比如 LinearLayout 巢狀多層、RelativeLayout 的多重巢狀等。

3.使用 ViewStub 來延遲載入檢視

如果佈局中包含複雜的檢視,可以考慮使用 ViewStub 來延遲載入這些檢視,以減少佈局的載入時間。

4.避免使用過多的巢狀佈局

巢狀佈局會增加布局的複雜度,導致渲染時間變長。因此應該儘量避免過多的巢狀佈局。

5.使用合適的佈局屬性

合理使用佈局屬性可以讓佈局更加簡潔、高效,比如使用 match_parent 和 wrap_content 來替代具體的畫素值。

6.避免在佈局檔案中使用過多的 include 標籤

include 標籤可以重複使用佈局,但是過多的使用會增加布局層次和渲染時間,因此應該儘量避免在佈局檔案中使用過多的 include 標籤

主要是要弄明白布局的使用場景,從這幾個坑出發,寫程式碼的時候上點心。

另外學習約束佈局有一個很好的部落格推薦大家# 萬字長文 - 史上最全ConstraintLayout(約束佈局)使用詳解