APK瘦身
隨著業(yè)務(wù)迭代,apk體積逐漸變大。項(xiàng)目中積累的無用資源,未壓縮的圖片資源等,都為apk帶來了不必要的體積增加。而APK 的大小會(huì)影響應(yīng)用加載速度、使用的內(nèi)存量以及消耗的電量。
APK 結(jié)構(gòu)
APK 包含以下目錄:
META-INF/ :包含? CERT.SF 和? CERT.RSA 簽名文件,以及? MANIFEST.MF 清單文件。
assets/ :包含應(yīng)用的資源;應(yīng)用可以使用? AssetManager 對(duì)象檢索這些資源。
res/ :包含未編譯到? resources.arsc 中的資源(圖片、音視頻等)。
lib/ :包含特定于處理器軟件層的已編譯代碼。此目錄包含每種平臺(tái)類型的子目錄,如? armeabi 、armeabi-v7a 、 arm64-v8a 、 x86 、 x86_64 和? mips ?,F(xiàn)在常用要求的(arm64-v8a)其他可以不考慮
主要優(yōu)化:assets,res,lib文件夾下的文件。
APK 還包含以下文件。
resources.arsc :包含了被編譯的資源。該文件包含了res/values目錄的所有配置的 xml 內(nèi)容。打包工具將 xml 內(nèi)容編譯成二進(jìn)制形式并壓縮。這些內(nèi)容包含了語(yǔ)言字符串和styles,還包含了那些內(nèi)容雖然不直接存儲(chǔ)在resources.arsc文件中,但是給定了該內(nèi)容的路徑,比如布局文件和圖片。所以又叫 資源映射表。
classes.dex :包含以 Dalvik/ART 虛擬機(jī)可理解的 DEX 文件格式編譯的類。
AndroidManifest.xml :包含了主要的Android配置文件。這個(gè)文件列出了應(yīng)用名稱、版本、訪問權(quán)限、引用的庫(kù)文件。該文件使用二進(jìn)制 xml 格式存儲(chǔ)。(譯注:該文件還能看到應(yīng)用的minSdkVersion, targetSdkVersion等信息)
Android Size Analyzer
Android Size Analyzer 工具可輕松地發(fā)現(xiàn)和實(shí)施多種縮減應(yīng)用大小的策略
從菜單欄中依次選擇?Analyze > Analyze App Size,對(duì)當(dāng)前項(xiàng)目運(yùn)行應(yīng)用大小分

啟用資源縮減
如果在應(yīng)用的?build.gradle?文件中啟用了資源縮減:?shrinkResources,則 Gradle 在打包APK時(shí)可以自動(dòng)忽略未使用資源。 資源縮減只有在與代碼縮減:minifyEnabled 配合使用時(shí)才能發(fā)揮作用。在代碼縮減器移除所有不使用的代碼后,資源縮減器便可確定應(yīng)用仍要使用的資源,從而在打包時(shí)優(yōu)化這些資源 。

shrinkResources:資源壓縮
minifyEnabled?:代碼壓縮
移除未使用的備用資源
一般開發(fā)我們都會(huì)引入各種依賴,這些依賴可能包含各種備用資源,如中文、英文、日韓文等等。如果我們不需要這些語(yǔ)言(不做國(guó)際化需求)可以讓他們不打包進(jìn)入。Apk。
一鍵刪除無用資源
Android Studio給我們提供了一鍵移除所有無用的資源。從菜單欄中依次選擇?Refactor > Remove UnusedResources,但是這種方式不建議使用,因?yàn)槿绻迟Y源僅存在動(dòng)態(tài)獲取資源id 的方式,那么這個(gè)資源會(huì)被認(rèn)為沒有使用過,從而會(huì)直接被刪除。
動(dòng)態(tài)庫(kù)打包配置
目前Android打包可以支持如下CPU架構(gòu):
armeabi-v7a: 第7代 ARM v7,使用硬件浮點(diǎn)運(yùn)算,具有高級(jí)擴(kuò)展功能(支持 armeabi 和 armeabi-v7a,目前大部分手機(jī)都是這個(gè)架構(gòu))。
arm64-v8a :第8代,64位,包含AArch32、AArch64兩個(gè)執(zhí)行狀態(tài)對(duì)應(yīng)32、64bit(支持 armeabi-v7a、armeabi 和 arm64-v8a)。
x86 intel 32位:少數(shù)的平板應(yīng)用此架構(gòu)(支持 armeabi(性能有所損耗) 和 x86)。
x86_64 :intel 64位,少數(shù)的平板應(yīng)用此架構(gòu)(支持 x86 和 x86_64)。
目前市面上手機(jī)設(shè)備絕大多數(shù)都是arm架構(gòu),因此armv7a幾乎能兼容所有設(shè)備。大多數(shù)應(yīng)用只會(huì)打包armv7a的so在Apk中。對(duì)于第三方服務(wù),如百度地圖、Bugly等會(huì)提供全平臺(tái)的cpu架構(gòu)。因此我們可以進(jìn)行如下配置,指定只打包armv7a到apk,從而減少apk大小。

使用矢量圖
矢量圖可以創(chuàng)建與分辨率無關(guān)的圖標(biāo)和其他可伸縮媒體。使用這些圖形可以極大地減少 APK 占用的空間。 矢量圖片在 Android 中以?VectorDrawable?對(duì)象的形式表示。借助?VectorDrawable?對(duì)象,100 字節(jié)的文件可以生成與屏幕大小相同的清晰圖片。
不過,系統(tǒng)渲染每個(gè)?VectorDrawable?對(duì)象需要花費(fèi)大量時(shí)間,而較大的圖片則需要更長(zhǎng)的時(shí)間才能顯示在屏幕上。因此,建議僅在顯示小圖片時(shí)使用這些矢量圖



Tint著色器
雖然我們可以直接在 xml 文件中修改矢量圖的顏色,但是并不建議直接修改,我們一般讓矢量圖為黑色,然后用 Tint 著色器去修改矢量圖的顏色。


其他
使用精簡(jiǎn)版本的依賴:如protobuf-lite版本;對(duì)于分模塊的庫(kù)按需引入:如netty分模塊引入;
主動(dòng)移除無用代碼(開啟R8/Progurad自動(dòng)移除);
避免使用枚舉,使用?@IntDef?代替;
不常用功能模塊使用插件化加載;
開啟資源混淆:https://github.com/shwenzhang/AndResGuard;
支付寶刪除Dex debugItem https://juejin.im/post/6844903712201277448 ;
對(duì)于發(fā)布Google paly的應(yīng)用選擇使用:AAB https://developer.android.google.cn/guide/app-bundle