1. 程式人生 > 其它 >Android高階進階之路【七】Android效能優化總結

Android高階進階之路【七】Android效能優化總結

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

在Android應用優化方面,我們主要從以下4個方面進行優化:

  1. 穩定(記憶體溢位、崩潰)
  2. 流暢(卡頓)
  3. 耗損(耗電、流量、網路)
  4. 安裝包(APK瘦身)

記憶體優化


由於Android應用的沙箱機制,每個應用所分配的記憶體大小是有限度的,記憶體太低就會觸發LMK(Low Memory Killer)機制,進而會出現閃退現象。如果要對記憶體進行優化,就需要先搞懂java的記憶體是如何分配和回收的,關於這方面,可以重點參考下面的內容:
Java 垃圾回收器的GC機制,看這一篇就夠了
Android 記憶體洩漏常見案例及分析
Android應用記憶體洩漏的定位、分析與解決策略

分析工具


Memory Monitor 工具

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

Memory Analyzer工具

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

LeakCanary工具

LeakCanary是一個記憶體監測工具,該工具是Square公司出品的,所謂Square出品必屬精品,LeakCanary的官方地址為https://github.com/square/leakcanar,我們可以在Gradle裡引用它。

Android Lint 工具

Android Lint 是Android Sutido種整合的一個Android程式碼提示工具,它可以給佈局、程式碼提供非常強大的幫助。如果在佈局檔案中寫了三層冗餘的LinearLayout佈局,就會在編輯器右邊看到提示。當然這個是一個簡單的舉例,Lint的功能非常強大,大家應該養成寫完程式碼檢視Lint的習慣,這不僅讓你及時發現程式碼種隱藏的一些問題,更能讓你養成良好的程式碼風格,要知道,這些Lint提示可都是Google大牛們汗水合智慧的結晶。

其他建議

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

互動優化


互動是與使用者體驗最直接的方面,互動場景大概可以分為四個部分:UI 繪製、應用啟動、頁面跳轉、事件響應。對於上面四個方面,大致可以從以下兩個方面來進行優化:

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

我們知道,Android的繪製需要經過onMeasure、onLayout、onDraw等幾個步驟,所以佈局的層級越深、元素越多、耗時也就越長。還有就是Android 系統每隔 16ms 發出 VSYNC 訊號,觸發對 UI 進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的 60FPS。如果某個操作花費的時間是 24ms ,系統在得到 VSYNC 訊號時就無法正常進行正常渲染,這樣就發生了丟幀現象。

之所以出現卡頓現象,是因為有兩個原因:

  • 繪製任務太重,繪製一幀內容耗時太長
  • 主執行緒太忙,根據系統傳遞過來的 VSYNC 訊號來時還沒準備好資料導致丟幀

基於問題產生的原因,我們可以從以下幾個方面進行優化:

佈局優化

在Android種系統對View進行測量、佈局和繪製時,都是通過對View數的遍歷來進行操作的。如果一個View數的高度太高就會嚴重影響測量、佈局和繪製的速度。Google也在其API文件中建議View高度不宜哦過10層。現在版本種Google使用RelativeLayout替代LineraLayout作為預設根佈局,目的就是降低LineraLayout巢狀產生布局樹的高度,從而提高UI渲染的效率。
在佈局優化方面,我們可以從以下幾個方面進行優化:

  • 佈局複用,使用<include>標籤重用layout;
  • 提高顯示速度,使用<ViewStub>延遲View載入;
  • 減少層級,使用<merge>標籤替換父級佈局;
  • 注意使用wrap_content,會增加measure計算成本;
  • 刪除控制元件中無用屬性;

渲染優化

過度繪製是指在螢幕上的某個畫素在同一幀的時間內被繪製了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪製的操作,就會導致某些畫素區域被繪製了多次,從而浪費了多餘的 CPU 以及 GPU 資源。我們可以通過開啟手機的過渡繪製功能來檢測頁面是否被過度繪製。

為了避免過度繪製,我們可以從以下幾個方面進行優化:

  • 佈局上的優化,移除 XML 中非必須的背景,移除 Window 預設的背景、按需顯示佔位背景圖片。
  • 自定義View優化,使用 canvas.clipRect()來幫助系統識別那些可見的區域,只有在這個區域內才會被繪製。

啟動優化

應用一般都有閃屏頁,優化閃屏頁的 UI 佈局,可以通過 Profile GPU Rendering 檢測丟幀情況。
也可以通過啟動載入邏輯優化。可以採用分佈載入、非同步載入、延期載入策略來提高應用啟動速度。
資料準備。資料初始化分析,載入資料可以考慮用執行緒初始化等策略。

重新整理優化

Android開發中,通常是非同步操作頁面的,因此需要可以從重新整理優化上來優化應用,主要有兩個原則:

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

動畫優化

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

耗電優化

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

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

網路優化

對於網路的優化,可以從以下幾個方面著手進行:

圖片網路優化

例如,針對網路情況,返回不同的圖片資料,一種是高清大圖,一種是正常圖片,一種是縮略小圖。當用戶處於wifi下給控制元件設定高清大圖,當4g或者3g模式下載入正常圖片,當弱網條件下載入縮圖。

網路資料優化

移動端獲取網路資料優化可以從以下幾點著手:

  • 連線複用:節省連線建立時間,如開啟 keep-alive。
    對於Android來說預設情況下HttpURLConnection和HttpClient都開啟了keep-alive。只是2.2之前HttpURLConnection存在影響連線池的Bug,具體可見:Android HttpURLConnection及HttpClient選擇
  • 請求合併:即將多個請求合併為一個進行請求,比較常見的就是網頁中的CSS Image Sprites。如果某個頁面內請求過多,也可以考慮做一定的請求合併。
  • 減少請求資料的大小:對於post請求,body可以做gzip壓縮的,header也可以做資料壓縮。返回資料的body也可以做gzip壓縮,body資料體積可以縮小到原來的30%左右。

異常攔截優化

在獲取資料的流程中,訪問介面和解析資料時都有可能會出錯,我們可以通過攔截器在這兩層攔截錯誤。

  • 在訪問介面時,我們不用設定攔截器,因為一旦出現錯誤,Retrofit會自動丟擲異常。比如,常見請求異常404,500,503等等。
  • 在解析資料時,我們設定一個攔截器,判斷Result裡面的code是否為成功,如果不成功,則要根據與伺服器約定好的錯誤碼來丟擲對應的異常。比如,token失效,禁用同賬號登陸多臺裝置,缺少引數,引數傳遞異常等等。

APK瘦身


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

在Android Studio工具欄裡,開啟build–>Analyze APK, 選擇要分析的APK包 ,可以看到apk的相關資訊,如下所示:

Android的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圖片格式等。
  • 外掛化,比如功能模組放在伺服器上,按需下載,可以減少安裝包大小。

本文轉自 https://blog.csdn.net/xiangzhihong8/article/details/92800490,如有侵權,請聯絡刪除。

相關視訊:

【2021最新版】Android studio安裝教程+Android(安卓)零基礎教程視訊(適合Android 0基礎,Android初學入門)_嗶哩嗶哩_bilibili

Android高階UI效能優化——FlowLayout流式佈局專案實戰長_嗶哩嗶哩_bilibili

Android高階UI效能優化——View的Measure原理應用與xml解析過程原理講解_嗶哩嗶哩_bilibili

Android高階UI效能優化——LayoutInflater.inflate函式意義與引數說明_嗶哩嗶哩_bilibili

Android高階UI效能優化——ViewPager巢狀Fragment UI 模式效能優化_嗶哩嗶哩_bilibili