Android app 效能最佳化的思考--效能卡頓不好的原因在哪?

來源:互聯網
上載者:User

標籤:待機   檔案夾   ros   垃圾收集   函數調用   規則   大數   monitor   持久性   

說到 Android 系統手機,大部分人的印象是用了一段時間就變得有點卡頓,有些程式在運行期間莫名其妙的出現崩潰,開啟系統檔案夾一看,發現多了很多檔案,然後用手機管家 APP 不斷地進行清理最佳化 ,才感覺運行速度稍微提高了點,就算手機在各種效能跑分軟體面前分數遙遙領先,還是感覺無論有多大的記憶體空間都遠遠不夠用。相信每個使用 Android 系統的使用者都有過以上類似經曆,確實,Android 系統在流暢性方面不如 IOS 系統,為何呢,明明在看手機硬體設定上時,Android 裝置都不會輸於 IOS 裝置,甚至都強於它,關鍵是在於軟體上。造成這種現象的原因是多方面的,簡單羅列幾點如下:

  • 其實近年來,隨著 Android 版本不斷迭代,Google 提供的Android 系統已經越來越流暢,目前最新發行的版本是 Android 8.0 Oreo 。但是在國內大部分使用者用的 Android 手機系是各大廠商定製過的版本,往往不是最新的原生系統核心,可能絕大多數還停留在 Android 5.0 系統上,甚至 Android 6.0 以上所佔比例還偏小,更新存在延遲性。
  • 由於 Android 系統源碼是開放的,每個人只要遵從相應的協議,就可以對源碼進行修改,那麼國內各個廠商就把基於 Android 源碼改造成自己對外發布的系統,比如我們熟悉的小米手機 Miui 系統、華為手機 EMUI 系統、Oppo 手機 ColorOS 系統等。由於每個廠商都修改過 Android 原生系統源碼,這裡面就會引發一個問題,那就是著名的Android 片段化問題,本質就是不同 Android 系統的應用相容性不同,達不到一致性。
  • 由於存在著各種 Android 片段化和相容性問題,導致 Android 開發人員在開發應用時需要對不同系統進行適配,同時每個 Android 開發人員的開發水平參差不齊,寫出來的應用效能也都存在不同類型的問題,導致使用者在使用過程中使用者體驗感受不同,那麼有些問題使用者就會轉化為 Android 系統問題,進而影響對Android 手機的評價。
效能最佳化

今天想說的重點是Android APP 效能最佳化,也就是在開發應用程式時應該注意的點有哪些,如何更好地提高使用者體驗。一個好的應用,除了要有迷人的功能和互動之外,在效能上也應該有高的要求,即時應用非常具有特色,在產品前期可能吸引了部分使用者,但是使用者體驗不好的話,也會給產品帶來不好的口碑。那麼一個好的應用應該如何定義呢?主要有以下三方面:

  • 業務/功能
  • 符合邏輯的互動
  • 優秀的效能

眾所周知,Android 系統作為以行動裝置為主的作業系統,硬體設定是有一定的限制的,雖然配置現在越來越進階,但仍然無法與 PC 相比,在 CPU 和記憶體上使用不合理或者耗費資源多時,就會碰到記憶體不足導致的穩定性問題、CPU 限定太多導致的卡頓問題等。

面對問題時,大家想到的都是聯絡使用者,然後查看日誌,但殊不知有關效能類問題的反饋,原因也非常難找,日誌大多用處不大,為何呢?因為效能問題大部分是非必現的問題,問題定位很難複現,而又沒有關鍵的日誌,當然就無法找到原因了。這些問題非常影響使用者體驗和功能使用,所以瞭解一些效能最佳化的一些解決方案就顯得很重要了,並在實際的項目中最佳化我們的應用,進而提高使用者體驗。

四個方面

可以把使用者體驗的效能問題主要總結為4個類別:

  • 流暢
  • 穩定
  • 省電、省流量
  • 安裝包小

效能問題的主要原因是什麼,原因有相同的,也有不同的,但歸根到底,不外乎記憶體使用量、代碼效率、合適的策略邏輯、代碼品質、安裝包體積這一類問題,整理歸類如下:

可以看到,打造一個高品質的應用應該以4個方向為目標:快、穩、省、小。

快:使用時避免出現卡頓,響應速度快,減少使用者等待的時間,滿足使用者期望。

穩:減低 crash 率和 ANR 率,不要在使用者使用過程中崩潰和無響應。

省:節省流量和耗電,減少使用者使用成本,避免使用時導致手機發燙。

小:安裝包小可以降低使用者的安裝成本。

要想達到這4個目標,具體實現是在右邊框裡的問題:卡頓、記憶體使用量不合理、代碼品質差、代碼邏輯亂、安裝包過大,這些問題也是在開發過程中碰到最多的問題,在實現業務需求同時,也需要考慮到這點,多花時間去思考,如何避免功能完成後再來做最佳化,不然的話等功能實現後帶來的維護成本會增加。

卡頓最佳化

Android 應用啟動慢,使用時經常卡頓,是非常影響使用者體驗的,應該盡量避免出現。卡頓的情境有很多,按情境可以分為4類:UI 繪製、應用啟動、頁面跳轉、事件響應,

這4種卡頓情境的根本原因可以分為兩大類:

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

引起卡頓的原因很多,但不管怎麼樣的原因和情境,最終都是通過裝置螢幕上顯示來達到使用者,歸根到底就是顯示有問題,所以,要解決卡頓,就要先瞭解 Android 系統的顯示原理。

Android系統顯示原理

Android 顯示過程可以簡單概括為:Android 應用程式把經過測量、布局、繪製後的 surface 快取資料,通過 SurfaceFlinger 把資料渲染到顯示螢幕上, 通過 Android 的重新整理機制來重新整理資料。也就是說應用程式層負責繪製,系統層負責渲染,通過處理序間通訊把應用程式層需要繪製的資料傳遞到系統層服務,系統層服務通過重新整理機制把資料更新到螢幕上。

我們都知道在 Android 的每個 View 繪製中有三個核心步驟:Measure、Layout、Draw。具體實現是從 ViewRootImp 類的performTraversals() 方法開始執行,Measure 和 Layout都是通過遞迴來擷取 View 的大小和位置,並且以深度作為優先順序,可以看出層級越深、元素越多、耗時也就越長。

真正把需要顯示的資料渲染到螢幕上,是通過系統級進程中的 SurfaceFlinger 服務來實現的,那麼這個SurfaceFlinger 服務主要做了哪些工作呢?如下:

  • 響應用戶端事件,建立 Layer 與用戶端的 Surface 建立串連。
  • 接收用戶端資料及屬性,修改 Layer 屬性,如尺寸、顏色、透明度等。
  • 將建立的 Layer 內容重新整理到螢幕上。
  • 維持 Layer 的序列,並對 Layer 最終輸出做出裁剪計算。

既然是兩個不同的進程,那麼肯定是需要一個跨進程的通訊機制來實現資料傳遞,在 Android 顯示系統中,使用了 Android 的匿名共用記憶體:SharedClient,每一個應用和 SurfaceFlinger 之間都會建立一個SharedClient ,然後在每個 SharedClient 中,最多可以建立 31 個 SharedBufferStack,每個 Surface 都對應一個 SharedBufferStack,也就是一個 Window。

一個 SharedClient 對應一個Android 應用程式,而一個 Android 應用程式可能包含多個視窗,即 Surface 。也就是說 SharedClient 包含的是 SharedBufferStack的集合,其中在顯示重新整理機制中用到了雙緩衝和三重緩衝技術。最後總結起來顯示整體流程分為三個模組:應用程式層繪製到緩衝區,SurfaceFlinger 把緩衝區資料渲染到螢幕,由於是不同的進程,所以使用 Android 的匿名共用記憶體 SharedClient 緩衝需要顯示的資料來達到目的。

除此之外,我們還需要一個名詞:FPS。FPS 表示每秒傳遞的幀數。在理想情況下,60 FPS 就感覺不到卡,這意味著每個繪製時間長度應該在16 ms 以內。但是 Android 系統很有可能無法及時完成那些複雜的頁面渲染操作。Android 系統每隔 16ms 發出 VSYNC 訊號,觸發對 UI 進行渲染,如果每次渲染都成功,這樣就能夠達到流暢的畫面所需的 60FPS。如果某個操作花費的時間是 24ms ,系統在得到 VSYNC 訊號時就無法正常進行正常渲染,這樣就發生了丟幀現象。那麼使用者在 32ms 內看到的會是同一幀畫面,這種現象在執行動畫或滑動列表比較常見,還有可能是你的 Layout 太過複雜,層疊太多的繪製單元,無法在 16ms 完成渲染,最終引起重新整理不及時。

卡頓根本原因

根據Android 系統顯示原理可以看到,影響繪製的根本原因有以下兩個方面:

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

繪製耗時太長,有一些工具可以協助我們定位問題。主線程太忙則需要注意了,主線程關鍵職責是處理使用者互動,在螢幕上繪製像素,並進行載入顯示相關的資料,所以特別需要避免任何主線程的事情,這樣應用程式才能保持對使用者操作的即時響應。總結起來,主線程主要做以下幾個方面工作:

  • UI 生命週期控制
  • 系統事件處理
  • 訊息處理
  • 介面布局
  • 介面繪製
  • 介面重新整理

除此之外,應該盡量避免將其他處理放在主線程中,特別複雜的資料計算和網路請求等。

效能分析工具

效能問題並不容易複現,也不好定位,但是真的碰到問題還是需要去解決的,那麼分析問題和確認問題是否解決,就需要藉助相應的的調試工具,比如查看 Layout 層次的 Hierarchy View、Android 系統上帶的 GPU Profile 工具和靜態代碼檢查工具 Lint 等,這些工具對效能最佳化起到非常重要的作用,所以要熟悉,知道在什麼情境用什麼工具來分析。

1,Profile GPU Rendering

在手機開發人員模式下,有一個卡頓偵查工具叫做:Profile GPU Rendering,

它的功能特點如下:

  • 一個圖形監測工具,能即時反應當前繪製的耗時
  • 橫軸表示時間,縱軸表示每一幀的耗時
  • 隨著時間推移,從左至右的重新整理呈現
  • 提供一個標準的耗時,如果高於標準耗時,就表示當前這一幀丟失

2,TraceView

TraceView 是 Android SDK 內建的工具,用來分析函數調用過程,可以對 Android 的應用程式以及 Framework 層的代碼進行效能分析。它是一個圖形化的工具,最終會產生一個圖表,用於對效能分析進行說明,可以分析到每一個方法的執行時間,其中可以統計出該方法調用次數和遞迴次數,實際時間長度等參數維度,使用非常直觀,分析效能非常方便。

3,Systrace UI 效能分析

Systrace 是 Android 4.1及以上版本提供的效能資料採樣和分析工具,它是通過系統的角度來返回一些資訊。它可以協助開發人員收集 Android 關鍵子系統,如 surfaceflinger、WindowManagerService 等 Framework 部分關鍵模組、服務、View系統等運行資訊,從而協助開發人員更直觀地分析系統瓶頸,改進效能。Systrace 的功能包括跟蹤系統的 I/O 操作、核心工作隊列、CPU 負載等,在 UI 顯示效能分析上提供很好的資料,特別是在動畫播放不流暢、渲染卡等問題上。

最佳化建議

1,布局最佳化

布局是否合理主要影響的是頁面測量時間的多少,我們知道一個頁面的顯示測量和繪製過程都是通過遞迴來完成的,多叉樹遍曆的時間與樹的高度h有關,其時間複雜度 O(h),如果層級太深,每增加一層則會增加更多的頁面顯示時間,所以布局的合理性就顯得很重要。

那布局最佳化有哪些方法呢,主要通過減少層級、減少測量和繪製時間、提高複用性三個方面入手。總結如下:

  • 減少層級。合理使用 RelativeLayout 和 LinerLayout,合理使用Merge。
  • 提高顯示速度。使用 ViewStub,它是一個看不見的、不佔布局位置、佔用資源非常小的視圖對象。
  • 布局複用。可以通過 標籤來提高複用。
  • 儘可能少用wrap_content。wrap_content 會增加布局 measure 時計算成本,在已知寬高為固定值時,不用wrap_content 。
  • 刪除控制項中無用的屬性。

2,避免過度繪製

過度繪製是指在螢幕上的某個像素在同一幀的時間內被繪製了多次。在多層次重疊的 UI 結構中,如果不可見的 UI 也在做繪製的操作,就會導致某些像素地區被繪製了多次,從而浪費了多餘的 CPU 以及 GPU 資源。

如何避免過度繪製呢,如下:

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

3,啟動最佳化

通過對啟動速度的監控,發現影響啟動速度的問題所在,最佳化啟動邏輯,提高應用的啟動速度。啟動主要完成三件事:UI 布局、繪製和資料準備。因此啟動速度最佳化就是需要最佳化這三個過程:

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

4,合理的重新整理機制

在應用開發過程中,因為資料的變化,需要重新整理頁面來展示新的資料,但頻繁重新整理會增加資源開銷,並且可能導致卡頓發生,因此,需要一個合理的重新整理機制來提高整體的 UI 流暢度。合理的重新整理需要注意以下幾點:

  • 盡量減少重新整理次數。
  • 盡量避免後台有高的 CPU 線程運行。
  • 縮小重新整理地區。

5,其他

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

記憶體最佳化

在 Android 系統中有個垃圾記憶體回收機制,在虛擬機器層自動分配和釋放記憶體,因此不需要在代碼中分配和釋放某一塊記憶體,從應用程式層面上不容易出現記憶體流失和記憶體溢出等問題,但是需要記憶體管理。Android 系統在記憶體管理上有一個 Generational Heap Memory 模型,記憶體回收的大部分壓力不需要應用程式層關心, Generational Heap Memory 有自己一套管理機制,當記憶體達到一個閾值時,系統會根據不同的規則自動釋放系統認為可以釋放的記憶體,也正是因為 Android 程式把記憶體控制的權力交給了 Generational Heap Memory,一旦出現記憶體流失和溢出方面的問題,排查錯誤將會成為一項異常艱難的工作。除此之外,部分 Android 應用開發人員在開發過程中並沒有特別關注記憶體的合理使用,也沒有在記憶體方面做太多的最佳化,當應用程式同時運行越來越多的任務,加上越來越複雜的業務需求時,完全依賴 Android 的記憶體管理機制就會導致一系列效能問題逐漸呈現,對應用的穩定性和效能帶來不可忽視的影響,因此,解決記憶體問題和合理最佳化記憶體是非常有必要的。

Android記憶體管理機制

Android 應用都是在 Android 的虛擬機器上運行,應用 程式的記憶體配置與記憶體回收都是由虛擬機器完成的。在 Android 系統,虛擬機器有兩種運行模式:Dalvik 和 ART。

1,Java對象生命週期

一般Java對象在虛擬機器上有7個運行階段:

建立階段->應用階段->不可見階段->不可達階段->收集階段->終結階段->對象空間重新分配階段

2,記憶體配置

在 Android 系統中,記憶體配置實際上是對堆的分配和釋放。當一個 Android 程式啟動,應用進程都是從一個叫做 Zygote 的進程衍生出來,系統啟動 Zygote 進程後,為了啟動一個新的應用程式進程,系統會衍生 Zygote 進程產生一個新的進程,然後在新的進程中載入並運行應用程式的代碼。其中,大多數的 RAM pages 被用來分配給Framework 代碼,同時促使 RAM 資源能夠在應用所有進程之間共用。

但是為了整個系統的記憶體控制需要,Android 系統會為每一個應用程式都設定一個硬性的 Dalvik Heap Size 最大限制閾值,整個閾值在不同裝置上會因為 RAM 大小不同而有所差異。如果應用佔用記憶體空間已經接近整個閾值時,再嘗試分配記憶體的話,就很容易引起記憶體溢出的錯誤。

3,記憶體回收機制

我們需要知道的是,在 Java 中記憶體被分為三個地區:Young Generation(年輕代)、Old Generation(年老代)、Permanent Generation(持久代)。最近分配的對象會存放在 Young Generation 地區。對象在某個時機觸發 GC 回收垃圾,而沒有回收的就根據不同規則,有可能被移動到 Old Generation,最後累積一定時間在移動到 Permanent Generation 地區。系統會根據記憶體中不同的記憶體資料類型分別執行不同的 GC 操作。GC 通過確定對象是否被使用中的物件引用來確定是否收集對象,進而動態回收無任何引用的對象佔據的記憶體空間。但需要注意的是頻繁的 GC 會增加應用的卡頓情況,影響應用的流暢性,因此需要盡量減少系統 GC 行為,以便提高應用的流暢度,減小卡頓發生的機率。

記憶體分析工具

做記憶體最佳化前,需要瞭解當前應用的記憶體使用量現狀,通過現狀去分析哪些資料類型有問題,各種類型的分布情況如何,以及在發現問題後如何發現是哪些具體對象導致的,這就需要相關工具來協助我們。

1,Memory Monitor

Memory Monitor 是一款使用非常簡單的圖形化工具,可以很好地監控系統或應用的記憶體使用量情況,主要有以下功能:

  • 顯示可用和已用記憶體,並且以時間為維度即時反應記憶體配置和回收情況。
  • 快速判斷應用程式的運行緩慢是否由於過度的記憶體回收導致。
  • 快速判斷應用是否由於記憶體不足導致程式崩潰。

2,Heap Viewer

Heap Viewer 的主要功能是查看不同資料類型在記憶體中的使用方式,可以看到當前進程中的 Heap Size 的情況,分別有哪些類型的資料,以及各種類型資料佔比情況。通過分析這些資料來找到大的記憶體對象,再進一步分析這些大對象,進而通過最佳化減少記憶體開銷,也可以通過資料的變化發現記憶體流失。

3,Allocation Tracker

Memory Monitor 和 Heap Viewer 都可以很直觀且即時地監控記憶體使用量情況,還能發現記憶體問題,但發現記憶體問題後不能再進一步找到原因,或者發現一塊異常記憶體,但不能區別是否正常,同時在發現問題後,也不能定位到具體的類和方法。這時就需要使用另一個記憶體分析工具 Allocation Tracker,進行更詳細的分析, Allocation Tracker 可以分配追蹤記錄應用程式的記憶體配置,並列出了它們的呼叫堆疊,可以查看所有對象記憶體配置的周期。

4,Memory Analyzer Tool(MAT)

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

常見記憶體流失情境

如果在記憶體流失發生後再去找原因並修複會增加開發的成本,最好在編寫代碼時就能夠很好地考慮記憶體問題,寫出更高品質的代碼,這裡列出一些常見的記憶體流失情境,在以後的開發過程中需要避免這類問題。

  • 資源性對象未關閉。比如Cursor、File檔案等,往往都用了一些緩衝,在不使用時,應該及時關閉它們。
  • 註冊對象未登出。比如事件註冊後未登出,會導致觀察者列表中維持著對象的引用。
  • 類的靜態變數持有大資料對象。
  • 非靜態內部類的靜態執行個體。
  • Handler臨時性記憶體流失。如果Handler是非靜態,容易導致 Activity 或 Service 不會被回收。
  • 容器中的對象沒清理造成的記憶體流失。
  • WebView。WebView 存在著記憶體流失的問題,在應用中只要使用一次 WebView,記憶體就不會被釋放掉。

除此之外,記憶體流失可監控,常見的就是用LeakCanary 第三方庫,這是一個檢測記憶體流失的開源庫,使用非常簡單,可以在發生記憶體流失時警示,並且產生 leak tarce 分析泄漏位置,同時可以提供 Dump 檔案進行分析。

最佳化記憶體空間

沒有記憶體流失,並不意味著記憶體就不需要最佳化,在行動裝置上,由於物理裝置的儲存空間有限,Android 系統對每個應用進程也都分配了有限的堆記憶體,因此使用最小記憶體對象或者資源可以減小記憶體開銷,同時讓GC 能更高效地回收不再需要使用的對象,讓應用堆記憶體保持充足的可用記憶體,使應用更穩定高效地運行。常見做法如下:

  • 對象引用。強引用、軟引用、弱引用、虛引用四種參考型別,根據業務需求合理使用不同,選擇不同的參考型別。
  • 減少不必要的記憶體開銷。注意自動裝箱,增加記憶體複用,比如有效利用系統內建的資源、視圖複用、對象池、Bitmap對象的複用。
  • 使用最優的資料類型。比如針對資料類容器結構,可以使用ArrayMap資料結構,避免使用枚舉類型,使用緩衝Lrucache等等。
  • 圖片記憶體最佳化。可以設定位元影像規格,根據採樣因子做壓縮,用一些圖片緩衝方式對圖片進行管理等等。
穩定性最佳化

Android 應用的穩定性定義很寬泛,影響穩定性的原因很多,比如記憶體使用量不合理、代碼異常情境考慮不周全、代碼邏輯不合理等,都會對應用的穩定性造成影響。其中最常見的兩個情境是:Crash 和 ANR,這兩個錯誤將會使得程式無法使用,比較常用的解決方式如下:

  • 提高代碼品質。比如開發期間的代碼審核,看些代碼設計邏輯,業務合理性等。
  • 代碼靜態掃描工具。常見工具有Android Lint、Findbugs、Checkstyle、PMD等等。
  • Crash監控。把一些崩潰的資訊,異常資訊及時地記錄下來,以便後續分析解決。
  • Crash上傳機制。在Crash後,盡量先儲存日誌到本地,然後等下一次網路正常時再上傳日誌資訊。
耗電最佳化

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

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

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

  • 計算最佳化,避開浮點運算等。
  • 避免 WaleLock 使用不當。
  • 使用 Job Scheduler。
安裝包大小最佳化

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

常用應用安裝包的構成,:

我們可以看到:

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

效能最佳化不是更新一兩個版本就可以解決的,是持久性的需求,持續整合迭代反饋。在實際的項目中,在項目剛開始的時候,由於人力和項目完成時間限制,效能最佳化的優先順序比較低,等進入項目投入使用階段,就需要把優先順序提高,但在項目初期,在設計架構方案時,效能最佳化的點也需要提早考慮進去,這就體現出一個程式員的技術功底了。

什麼時候開始有效能最佳化的需求,往往都是從發現問題開始,然後分析問題原因及背景,進而尋找最優解決方案,最終解決問題,這也是日常工作中常會用到的處理方式。

Android app 效能最佳化的思考--效能卡頓不好的原因在哪?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.