天天看點

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

公司項目在不斷的改版疊代中,代碼在不斷的累加,終于apk包不負重負了,已經到了八十多M了。可能要換種方式表達,到目前為止沒有正真的往外推過,一直在内部執行7天讨論需求,5天代碼實作的階段。你在寫上個版本的内容,好了,下個版本的更新内容已經定稿了。基于這種快速開發的現狀,我們app優化前已經有87.1M了,包大了,營運說這樣轉化不高,隻能好好搞一下咯。優化過後包大小為23.1M(優化了73%,不要說我标題黨)。好了好了,我要闡述我的apk超級無敵魔鬼瘦身之心得了。

1. 結構分析

首先上傳一張瘦身前通過Analyze app分析出來的圖檔(打開方式:Android Studio下 ——> Build——> Analyze app):

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

APK包結構如下:

1. lib/: 包含特定于處理器軟體層的編譯代碼。該目錄包含了每種平台的子目錄,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips。大多數情況下我們可以隻用一種armeabi-v7a,後面會講到原因。

2. assets/: 包含應用可以使用AssetManager對象檢索的應用資源。

3. res/: 包含未編譯到的資源 resources.arsc,主要有圖檔資源檔案。

4. META-INF/: 包含CERT.SF和 CERT.RSA簽名檔案以及MANIFEST.MF 清單檔案。

5. resources.arsc: 包含已編譯的資源。該檔案包含res/values/ 檔案夾所有配置中的XML内容。打包工具提取此XML内容,将其編譯為二進制格式,并将内容歸檔。此内容包括語言字元串和樣式,以及直接包含在resources.arsc檔案中的内容路徑 ,例如布局檔案和圖像。

6. classes.dex: 包含以Dalvik / ART虛拟機可了解的DEX檔案格式編譯的類。

7. AndroidManifest.xml: 包含核心Android清單檔案。該檔案列出應用程式的名稱,版本,通路權限和引用的庫檔案。該檔案使用Android的二進制XML格式。

通過分析圖可以知道,目前app主要是so檔案占比比較大,占了31.7M,占了整個應用是38.2%。其次是assets目錄,整個目錄占了32M,第三就是資源檔案res目錄了。是以接下來我們處理步驟就是按這個順序來處理。(簡單說下圖中的Raw File Size(磁盤解壓後的大小)和DownLoad Size(從應用商店下載下傳的大小),如果想了解更多關于Analyaer分析的知識,可以參考這篇文章使用APK Analyzer分析你的APK),分析了包結構組成之後,我們可以開始瘦身操作了。

2.具體實操

1. 對lib目錄下的檔案進行瘦身處理

1. 修改lib配置:

參考資料

so檔案的優化:通常我們在使用NDK開發的時候,我們經常會有如下這麼一段代碼:

ndk {
 //設定支援的so庫架構
 abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64", "armeabi"
 }

![](https://upload-images.jianshu.io/upload_images/15217452-a164a611526fa4bc?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

           
Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

最後我的修改代碼如下:

ndk {
 //設定支援的so庫架構
 abiFilters "armeabi-v7a"
 }
           

接下來說明這麼做的依據:

看上面圖分析,armeabi-v7主要不支援ARMv5(1998年誕生)和ARMv6(2001年誕生).目前這兩款處理器的手機裝置基本不在我公司的适配範圍(市場占比太少)。

而許多基于 x86 的裝置也可運作 armeabi-v7a 和 armeabi NDK 二進制檔案。對于這些裝置,主要 ABI 将是 x86,輔助 ABI 是 armeabi-v7a。

最後總結一點:如果适配版本高于4.1版本,可以直接像我上面這樣寫,當然,如果armeabi-v7a不是裝置主要ABI,那麼會在性能上造成一定的影響。

好了,我們再打一次包試試。

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後
Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

确實有點震驚,一下子包小了這麼多,從87.1M到51.9M,容我好好算算少了多少M.趕快讓測試幫忙測一下。基于之前的理論知識,心裡還是有點底。果然,測試效果和之前是一樣的。心裡的石頭先落下羅。

2. 重新編譯so檔案,用更小的庫代替

相信很多開發者都有這種苦惱,很多第三方我們導入進來隻用到其中很小一部分功能,大部分功能都是我們用不上的。這時候我們找到源代碼,将我們需要的那部分代碼提取出來,重新編譯成新的so檔案,再導入到我們項目中。當然,如果之前沒有編譯過so檔案,這部分建議做最後的優化去處理。不然你會遇到很多問題。上一波處理後的效果圖:

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

這裡說下,因為項目中有使用到ffmpeg庫,之前導入的第三方的放在assets檔案夾下,重寫編寫後的so庫檔案放在lib檔案夾下,是以lib檔案夾反而大了。從51.9M到35.6M,效果還是蠻不錯的。

對了,别問我為什麼assets檔案夾下為什麼還有12.6M資源,因為很多.mp3都是第三方的人臉識别必備配置檔案,我也很無奈。

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

2. 優化res,assets檔案大小

1. 手動lint檢查,手動删除無用資源

在Android Studio中打開“Analyze” 然後選擇"Inspect Code…",範圍選擇整個項目,然後點選"OK"。配置如下:

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

2. 使用tinypng等圖檔壓縮工具對圖檔進行壓縮。

打開網址,将大圖檔導入到tinypng,替換之前的圖檔資源。

3. 大部分圖檔使用Webp格式代替。

可以給UI提要求,讓他們将圖檔資源設定為Webp格式,這樣的話圖檔資源會小很多。如果想了解更多關于webp,請點選這裡webp,當然,如果對圖檔顔色通道要求不高,可以考慮轉jpg,最好用webp,因為效果更佳。

4. 盡量不要在項目中使用幀動畫

一個幀動畫幾十張圖檔,再怎麼壓縮都還是占很大記憶體比重的。是以建議是讓UI去搞,這裡可以參考使用lottie-android,如果項目中動畫效果多的話效果更加明顯。當然這就要辛苦我們UI設計師大大了。

5. 使用gradle開啟shrinkResources

移除無用資源檔案,下面是我的配置:

buildTypes {
 release {
 // 不顯示Log
 buildConfigField "boolean", "LOG_DEBUG", "false"
 //混淆
 minifyEnabled true
 // 移除無用的resource檔案
 shrinkResources true
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
 signingConfig signingConfigs.release
 }
 }
           

通過上述步驟操作,apk效果如下:

Android性能優化之APK瘦身詳解(瘦身73%)1. 結構分析APK包結構如下:2.具體實操2. 優化res,assets檔案大小3. 總結最後

3. 減少chasses.dex大小

classes.dex中包含了所有的java代碼,當你打包時,gradle會将所有模闆力的.class檔案轉換成classes.dex檔案,當然,如果方法數超過64K,将要新增其他檔案進行存儲。可以通過multidexing分多個檔案,比如我這裡的chasses2.dex。換句話說,就是減少代碼量。我們可以通過以下方法來實作:

  1. 盡量減少第三方庫的引用,這個在上面我們已經做過優化了。
  2. 避免使用枚舉,這裡特别去網上查了一下,得出的結論是,可能幾十個枚舉的記憶體占有量才相當一張圖檔這樣子,優化效果也不會特别明顯。當然,如果你是個追求極緻的人,我不反對你用靜态常量替代枚舉。
  3. 如果你的dex檔案太大,檢查是否引入了重複功能的第三方庫(圖檔加載庫,glide,picasso,fresco,image_loader,如果不是你一個人單獨開發完成的很容易出現這種情況),盡量做到一個功能點一個庫解決。

4. 其他

  1. 用7zip代替壓縮資源。
  2. 删除翻譯資源,隻保留中英文
  3. 嘗試将andorid support庫徹底踢出你的項目。
  4. 嘗試使用動态加載so庫檔案,插件化開發。
  5. 将大資源檔案放到服務端,啟動後自動下載下傳使用。

3. 總結

好了,說到這裡基本上就結束了,apk包從87.1M減小到了23.1M(優化了73%,不要說我标題黨)已經差不多了,關于第四部其他部分的優化我是沒有進行再操作的。因為公司營運覺得二三十M的包比較真實,太小了就太假了。是以我暫時就不進行優化了。如果再上面提到的部分通過所有将所有非啟動頁面首頁之外的所有資源,so庫放服務端,理論上apk包大小能在10M以内這樣子。當然我們有做到就不多加評價了。

最後

文末附上大廠學長給我的資料,内容包含:Android學習PDF+架構視訊+源碼筆記,進階架構技術進階腦圖、Android開發面試專題資料,進階進階架構資料 這幾塊的内容

分享給大家,非常适合近期有面試和想在技術道路上繼續精進的朋友。也是希望可以幫助到大家提升進階

相信它會給大家帶來很多收獲。如果你有需要的話,可以點選擷取!

如果你覺得自己學習效率低,缺乏正确的指導,可以加入資源豐富,學習氛圍濃厚的技術圈一起學習交流吧!