1. 程式人生 > >Android APP效能優化(最新總結)

Android APP效能優化(最新總結)

導語

安卓大軍浩浩蕩蕩,發展已近十個年頭,技術優化日異月新,如今Android 8.0 Oreo 都發布了,Android系統性能已經非常流暢了。但是,到了各大廠商手裡,改原始碼自定系統,使得Android原生系統變得魚龍混雜,然後到了不同層次的開發工程師手裡,因為技術水平的參差不齊,即使很多手機在跑分軟體效能非常高,開啟應用依然存在卡頓現象。另外,隨著產品內容迭代,功能越來越複雜,UI頁面也越來越豐富,也成為流暢執行的一種阻礙。綜上所述,對APP進行效能優化已成為開發者該有的一種綜合素質,也是開發者能夠完成高質量應用程式作品的保證。

思考優化

本著人道主義,一切從使用者體驗的角度去思考,當我們置身處地得把自己當做使用者去玩一款應用時候,那麼都會在意什麼呢?假如正在玩一款手遊,首先一定不希望玩著玩著突然閃退,然後就是遇到畫面內容很豐富的時候不希望卡頓,其次就是耗電和耗流量不希望太嚴重,最後就是版本更新的時候安裝包希望能小一點。好了,四個方面總結如下:
  1. 穩定(記憶體溢位、崩潰)
  2. 流暢(卡頓)
  3. 耗損(耗電、流量)
  4. 安裝包(APK瘦身)

一、穩定——記憶體優化

由於Android應用的沙箱機制,每個應用所分配的記憶體大小是有限度的,記憶體太低就會觸發LMK——Low Memory Killer機制,既會出現閃退現象。先搞懂java的記憶體是如何分配和回收的,問題就迎刃而解了。 相關文章: 知道記憶體是如何分配和記憶體回收機制後,就算對記憶體優化有一點的認識和掌握了。

使用分析工具

  • Memory Monitor 工具:
它是Android Studio自帶的一個記憶體監視工具,它可以很好地幫助我們進行記憶體實時分析。通過點選Android Studio右下角的Memory Monitor標籤,開啟工具可以看見較淺藍色代表free的記憶體,而深色的部分代表使用的記憶體從記憶體變換的走勢圖變換,可以判斷關於記憶體的使用狀態,例如當記憶體持續增高時,可能發生記憶體洩漏;當記憶體突然減少時,可能發生GC等。
  • Memory Analyzer工具:

MAT 是一個快速,功能豐富的 Java Heap 分析工具,通過分析 Java 程序的記憶體快照 HPROF 分析,從眾多的物件中分析,快速計算出在記憶體中物件佔用的大小,檢視哪些物件不能被垃圾收集器回收,並可以通過檢視直觀地檢視可能造成這種結果的物件。

  • LeakCanary工具:
簡單,傻瓜式操作。這個工具是在Github開源的,是Square公司出品的,不是有一句話嘛,Square出品必屬精品,https://github.com/square/leakcanary我們可以在Gradle裡引用它。
  • Android Lint 工具:
是Android Sutido種整合的一個Android程式碼提示工具,它可以給你佈局、程式碼提供非常強大的幫助。如果在佈局檔案中寫了三層冗餘的LinearLayout佈局,就會在編輯器右邊看到提示。當然這個是一個簡單的舉例,Lint的功能非常強大,大家應該養成寫完程式碼檢視Lint的習慣,這不僅讓你及時發現程式碼種隱藏的一些問題,更能讓你養成良好的程式碼風格,要知道,這些Lint提示可都是Google大牛們汗水合智慧的結晶。

穩定性建議

影響穩定性的原因很多,比如記憶體使用不合理、程式碼異常場景考慮不周全、程式碼邏輯不合理等,都會對應用的穩定性造成影響。其中最常見的兩個場景是:Crash 和 ANR,這兩個錯誤將會使得程式無法使用。所以做好Crash監控,把崩潰資訊、異常資訊收集記錄起來,以便後續分析;合理使用主執行緒處理業務,不要在主執行緒中做耗時操作,防止ANR程式無響應發生。

二、流暢——互動優化

互動是與使用者體驗最直接的方面,互動場景大概分為四個部分:UI 繪製、應用啟動、頁面跳轉、事件響應,如圖:

四個方面大致歸為如下兩類:

  • 介面繪製主要原因是繪製的層級深、頁面複雜、重新整理不合理,由於這些原因導致卡頓的場景更多出現在 UI 和啟動後的初始介面以及跳轉到頁面的繪製上。
  • 資料處理導致這種卡頓場景的原因是資料處理量太大,一般分為三種情況,一是資料在處理 UI 執行緒,二是資料處理佔用 CPU 高,導致主執行緒拿不到時間片,三是記憶體增加導致 GC 頻繁,從而引起卡頓。

總結原因:我們知道Android的繪製步驟是::Measure、Layout、Draw,所以佈局的層級越深、元素越多、耗時也就越長。還有就是Android 系統每隔 16ms 發出 VSYNC 訊號,觸發對 UI 進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的 60FPS。如果某個操作花費的時間是 24ms ,系統在得到 VSYNC 訊號時就無法正常進行正常渲染,這樣就發生了丟幀現象。那麼使用者在 32ms 內看到的會是同一幀畫面,無法在 16ms 完成渲染,最終引起重新整理不及時。兩個根本原因:

  1. 繪製任務太重,繪製一幀內容耗時太長。

  2. 主執行緒太忙,根據系統傳遞過來的 VSYNC 訊號來時還沒準備好資料導致丟幀。

建議1:佈局優化

在Android種系統對View進行測量、佈局和繪製時,都是通過對View數的遍歷來進行操作的。如果一個View數的高度太高就會嚴重影響測量、佈局和繪製的速度。Google也在其API文件中建議View高度不宜哦過10層。現在版本種Google使用RelativeLayout替代LineraLayout作為預設根佈局,目的就是降低LineraLayout巢狀產生布局樹的高度,從而提高UI渲染的效率。
  • 佈局複用,使用<include>標籤重用layout;
  • 提高顯示速度,使用<ViewStub>延遲View載入;
  • 減少層級,使用<merge>標籤替換父級佈局;
  • 注意使用wrap_content,會增加measure計算成本;

  • 刪除控制元件中無用屬性;

建議2:繪製優化

過度繪製是指在螢幕上的某個畫素在同一幀的時間內被繪製了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪製的操作,就會導致某些畫素區域被繪製了多次,從而浪費了多餘的 CPU 以及 GPU 資源。所以避免過度繪製:
  • 佈局上的優化。移除 XML 中非必須的背景,移除 Window 預設的背景、按需顯示佔位背景圖片

  • 自定義View優化。使用 canvas.clipRect()來幫助系統識別那些可見的區域,只有在這個區域內才會被繪製。


建議3:啟動優化

UI 佈局。應用一般都有閃屏頁,優化閃屏頁的 UI 佈局,可以通過 Profile GPU Rendering 檢測丟幀情況。

啟動載入邏輯優化。可以採用分佈載入、非同步載入、延期載入策略來提高應用啟動速度。

資料準備。資料初始化分析,載入資料可以考慮用執行緒初始化等策略。

建議4:重新整理優化

  • 少重新整理次數;
  • 縮小重新整理區域;

建議5:動畫優化

  • 在實現動畫效果時,需要根據不同場景選擇合適的動畫框架來實現。有些情況下,可以用硬體加速方式來提供流暢度。

三、節省——耗電優化

在移動裝置中,電池的重要性不言而喻,沒有電什麼都幹不成。對於作業系統和裝置開發商來說,耗電優化一致沒有停止,去追求更長的待機時間,而對於一款應用來說,並不是可以忽略電量使用問題,特別是那些被歸為“電池殺手”的應用,最終的結果是被解除安裝。因此,應用開發者在實現需求的同時,需要儘量減少電量的消耗。

在 Android5.0 以前,在應用中測試電量消耗比較麻煩,也不準確,5.0 之後專門引入了一個獲取裝置上電量消耗資訊的 API:Battery Historian。Battery Historian 是一款由 Google 提供的 Android 系統電量分析工具,和Systrace 一樣,是一款圖形化資料分析工具,直觀地展示出手機的電量消耗過程,通過輸入電量分析檔案,顯示消耗情況,最後提供一些可供參考電量優化的方法。

除此之外,還有一些常用方案可提供:

  • 計算優化,避開浮點運算等。

  • 避免 WaleLock 使用不當。

  • 使用 Job Scheduler。


四、APK瘦身

應用安裝包大小對應用使用沒有影響,但應用的安裝包越大,使用者下載的門檻越高,特別是在行動網路情況下,使用者在下載應用時,對安裝包大小的要求更高,因此,減小安裝包大小可以讓更多使用者願意下載和體驗產品。

常用應用安裝包的構成,如圖所示:

從圖中我們可以看到:

  • assets資料夾。存放一些配置檔案、資原始檔,assets不會自動生成對應的 ID,而是通過 AssetManager 類的介面獲取。

  • res。res 是 resource 的縮寫,這個目錄存放資原始檔,會自動生成對應的 ID 並對映到 .R 檔案中,訪問直接使用資源 ID。

  • META-INF。儲存應用的簽名信息,簽名信息可以驗證 APK 檔案的完整性。

  • AndroidManifest.xml。這個檔案用來描述 Android 應用的配置資訊,一些元件的註冊資訊、可使用許可權等。

  • classes.dex。Dalvik 位元組碼程式,讓 Dalvik 虛擬機器可執行,一般情況下,Android 應用在打包時通過 Android SDK 中的 dx 工具將 Java 位元組碼轉換為 Dalvik 位元組碼。

  • resources.arsc。記錄著資原始檔和資源 ID 之間的對映關係,用來根據資源 ID 尋找資源。

減少安裝包大小的常用方案

  • 程式碼混淆。使用proGuard 程式碼混淆器工具,它包括壓縮、優化、混淆等功能。

  • 資源優化。比如使用 Android Lint 刪除冗餘資源,資原始檔最少化等。

  • 圖片優化。比如利用 AAPT 工具對 PNG 格式的圖片做壓縮處理,降低圖片色彩位數等。

  • 避免重複功能的庫,使用 WebP圖片格式等。

  • 外掛化。比如功能模組放在伺服器上,按需下載,可以減少安裝包大小。


小結:

最後說一句,效能優化是一個非常具有挑戰性的工作,上面列出很多分析記憶體、優化記憶體的方法,但是真正優化工作遠不止這麼簡單,這裡只是列舉了一些入門的方法,而要進行完美的記憶體優化、記憶體分析絕非一日之功,需要開發者深厚的技術功底合耐心。