Android APP 性能優化

說到 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 性能優化,也就是在開發應用程序時應該注意的點有哪些,如何更好地提升用戶體驗。一個好的應用,除了要有吸引人的功能和交互以外,在性能上也應該有高的要求,即時應用很是具備特點,在產品前期可能吸引了部分用戶,可是用戶體驗很差的話,也會給產品帶來很差的口碑。那麼一個好的應用應該如何定義呢?主要有如下三方面:canvas

  • 業務/功能
  • 符合邏輯的交互
  • 優秀的性能

衆所周知,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,如圖:

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對象生命週期

通常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圖片格式等。
  • 插件化。好比功能模塊放在服務器上,按需下載,能夠減小安裝包大小。

小結

性能優化不是更新一兩個版本就能夠解決的,是持續性的需求,持續集成迭代反饋。在實際的項目中,在項目剛開始的時候,因爲人力和項目完成時間限制,性能優化的優先級比較低,等進入項目投入使用階段,就須要把優先級提升,但在項目初期,在設計架構方案時,性能優化的點也須要提前考慮進去,這就體現出一個程序員的技術功底了。

何時開始有性能優化的需求,每每都是從發現問題開始,而後分析問題緣由及背景,進而尋找最優解決方案,最終解決問題,這也是平常工做中常會用到的處理方式。

相關文章
相關標籤/搜索