Android性能優化之APK瘦身詳解(瘦身73%)

Android性能優化之APK瘦身詳解(瘦身73%)

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

Android性能優化之APK瘦身詳解(瘦身73%)

1. 結構分析

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

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格式。

2.具體實操

1. 對lib目錄下的文件進行瘦身處理

1. 修改lib配置:

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

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

最後我的修改代碼如下:

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,那麼會在性能上造成一定的影響。

參考文章:安卓app打包的時候還需要兼容armeabi麼?

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

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

2. 重新編譯so文件,用更小的庫代替

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

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

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

2. 優化res,assets文件大小

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

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

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

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

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

3. 大部分圖片使用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%)

這裡寫圖片描述

又優化了將近5M,別問我為什麼還有7.5M,裡面大量的gif和webp格式的動圖,都是UI丟給我的,一個2.7M.後面再慢慢和他細究這個問題。後面要做的兩部分,一部分是將資源文件下的所有gif圖放後臺下載處理,第二個是和UI討論下如何減小webp 動圖的大小(我看其他平臺只有100K的樣子,給我的就2.7M?)。

3. 減少chasses.dex大小

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

  1. 儘量減少第三方庫的引用,這個在上面我們已經做過優化了。

  2. 避免使用枚舉,這裡特別去網上查了一下,具體可以參考下這篇文章Android 中的 Enum 到底佔多少內存?該如何用?,得出的結論是,可能幾十個枚舉的內存佔有量才相當一張圖片這樣子,優化效果也不會特別明顯。當然,如果你是個追求極致的人,我不反對你用靜態常量替代枚舉。

  3. 如果你的dex文件太大,檢查是否引入了重複功能的第三方庫(圖片加載庫,glide,picasso,fresco,image_loader,如果不是你一個人單獨開發完成的很容易出現這種情況),儘量做到一個功能點一個庫解決。

關於classes.dex文件大小分析可以參考這篇譯文使用 APK Analyzer 分析你的 APK

4. 其他

  1. 刪除無用的語7zip代替

  2. 刪除翻譯資源,只保留中英文

  3. 嘗試將andorid support庫徹底踢出你的項目。

  4. 嘗試使用動態加載so庫文件,插件化開發。

  5. 將大資源文件放到服務端,啟動後自動下載使用。

3. 總結

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

文章本來是週三的差不多的,到今天才發,還是有點小偷懶了。最後祝大家五一快樂,出門玩的開心。如果你看到了這裡,覺得文章寫得不錯就給個讚唄?如果你覺得那裡值得改進的,請給我留言。一定會認真查詢,修正不足。謝謝。

Android性能優化之APK瘦身詳解(瘦身73%)

這裡寫圖片描述

文章主要參考文章如下,文章有少部分文字參考了下面文章中的語句。如果有侵犯到作者權益,請和我聯繫,查實後馬上刪除。

  1. Android APK 瘦身 - JOOX Music項目實戰

  2. APK 瘦身記,如何實現高達 53% 的壓縮效果

  3. 使用APK Analyzer分析你的APK

  4. 安卓app打包的時候還需要兼容armeabi麼?

  5. Android 中的 Enum 到底佔多少內存?該如何用?


分享到:


相關文章: