前言
隨着項目的發展,我們的 APK 會越來越大。這就意味着推廣的成本會增加,用戶在下載的時候會用掉更多的流量。上傳應用市場的時候往往也會有大小的限制。如何爲 APK 瘦身就成爲迫在眉睫的任務。這篇文章總結了爲 APK 瘦身的一些經驗。
APK 的結構
標準的 APK 的目錄中包含以下文件
classes.dex – 是 java 源碼編譯後生成的 java 字節碼文件
resources.arsc – 編譯後的二進制資源文件
AndroidManifest.xml – 每個應用都必須定義和包含的,它描述了應用的名字、版本、權限、引用的庫文件等等信息
assets – 存放一些配置文件(比如 webview 本地資源、圖片資源等等),這些文件的內容在程序運行過程中可以通過相關的 API 獲得。
META-INF – META-INF目錄下存放的是簽名信息,用來保證apk包的完整性和系統的安全。
lib – 存放第三方庫文件,lib 目錄下的子目錄 armeabi 存放的是一些 so 文件
res – 存放資源文件。包括圖片、字符串、 raw 文件夾下面的音頻文件、各種xml文件等等。
決定 APK 大小的主要是 classes.dex 、lib 和 res。
對 classes.dex 的優化通過代碼混淆,刪掉不必要的 jar 包和代碼這裏不做詳細的介紹。這裏主要介紹減小 lib 和 res 的方法。
優化 res
在 res 中主要存放的是一些資源文件,比如圖片等等。對 res 的優化主要有:
優化 lib
一個硬件設備對應一個架構(mips、arm 或者 x86),只保留與設備架構相關的庫文件夾,可以大大降低 lib 文件夾的大小。筆者發現,無論是 mips 還是 x86 架構的手機都支持 arm 的 so。所以我們可以只保留 arm 的 so。我們需要在項目的 build.gradle 中加入如下配置,就可以使其他架構的手機支持 arm 的 so。
defaultConfig {
multiDexEnabled = true
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
這樣配置以後,在打包的時候回自動過濾掉除了 armeabi 和 armeabi-v7a 之外的架構的 so,並在運行的時候運行 arm 的 so。
結語
筆者在開發過程中遇到的問題是引用的第三方庫太多。而每個庫都要支持不同的架構,這就導致 so 文件的體積快速增長,從而 APK 的體積也迅速變大。使用上述配置之後,把其他的架構的 so 刪除,從而使 APK 的大小減了下來。