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

默認標題_官方公衆號首圖_2018.04.29.png

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

目錄以下: java

文章主要內容從理論出發,再作實際操做。分爲下面幾個方面:1. 結構分析, 2.具體實操 3. 總結 4. 參考資料android

1. 結構分析

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

這裏寫圖片描述

APK包結構以下:github

  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),分析了包結構組成以後,咱們能夠開始瘦身操做了。web

2.具體實操

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

1. 修改lib配置:

參考資料 so文件的優化:一般咱們在使用NDK開發的時候,咱們常常會有以下這麼一段代碼:性能優化

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

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-xNDtH3zt-1571353784450)(upload-images.jianshu.io/upload_imag…)]bash

最後個人修改代碼以下:微信

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麼?架構

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

這裏寫圖片描述

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-Xv3lhgYo-1571353784451)(upload-images.jianshu.io/upload_imag…)] 確實有點震驚,一會兒包小了這麼多,從87.1M到51.9M,容我好好算算少了多少M.趕快讓測試幫忙測一下。基於以前的理論知識,內心仍是有點底。果真,測試效果和以前是同樣的。內心的石頭先落下羅。

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

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

這裏寫圖片描述
這裏說下,由於項目中有使用到ffmpeg庫,以前導入的第三方的放在assets文件夾下,重寫編寫後的so庫文件放在lib文件夾下,因此lib文件夾反而大了。從51.9M到35.6M,效果仍是蠻不錯的。

對了,別問我爲何assets文件夾下爲何還有12.6M資源,由於不少.mp3都是第三方的人臉識別必備配置文件,我也很無奈。

這裏寫圖片描述

2. 優化res,assets文件大小

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

在Android Studio中打開「Analyze」 而後選擇"Inspect Code...",範圍選擇整個項目,而後點擊"OK"。配置以下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aczX7vG1-1571353784454)(upload-images.jianshu.io/upload_imag…)]

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效果以下:

這裏寫圖片描述

又優化了將近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. 總結

好了,說道這裏基本上就結束了,apk包從87.1M減少到了23.1M(優化了73%,不要說我標題黨)已經差很少了,關於第四部其餘部分的優化我是沒有進行再操做的。由於公司運營以爲二三十M的包比較真實,過小了就太假了。因此我暫時就不進行優化了。若是再上面提到的部分經過全部將全部非啓動頁面首頁以外的全部資源,so庫放服務端,理論上apk包大小能在10M之內這樣子。固然咱們有作到就很少加評價了。最後,若是對插件化開發感興趣的話能夠參考下這篇文章Android全面插件化方案-RePlugin踩坑。最後,若是你在Android上有什麼疑問,能夠添加個人同名微信公衆號「aserbaocool」和我一塊交流。

文章原本是週三的差很少的,到今天才發,仍是有點小偷懶了。最後祝你們五一快樂,出門玩的開心。若是你看到了這裏,以爲文章寫得不錯就給個讚唄?若是你以爲那裏值得改進的,請給我留言。必定會認真查詢,修正不足。謝謝。
這裏寫圖片描述

4. 參考資料:

文章主要參考文章以下,文章有少部分文字參考了下面文章中的語句。若是有侵犯到做者權益,請和我聯繫,查實後立刻刪除。

  1. Android APK 瘦身 - JOOX Music項目實戰
  2. APK 瘦身記,如何實現高達 53% 的壓縮效果
  3. 使用APK Analyzer分析你的APK
  4. 安卓app打包的時候還須要兼容armeabi麼?
  5. 百度百科webp
  6. Android 中的 Enum 到底佔多少內存?該如何用?

推薦閱讀:Android性能優化以內存泄漏無處可藏(圖文)

相關文章
相關標籤/搜索