Android的安裝包APK文件本身就是個(gè)壓縮文件。把后綴名改成.zip,用解壓軟件解壓后,就能看到安裝包的內(nèi)容。

從上圖可以看到,安裝包內(nèi)的文件結(jié)構(gòu)是:
- assets 資源文件
- res 資源文件
- *.dex Dalvik字節(jié)碼
- META-INF 簽名信息
- lib so庫(kù)
要減小安裝包的體積本質(zhì)就是要減少包內(nèi)的文件的大小。接下來(lái)我們依次來(lái)看如何減少這些文件的大小
圖片資源
- 能用shape就絕不用圖片。對(duì)于純色或漸變的圖片,能用shape渲染的就優(yōu)先使用shape。不僅文件體積小,還渲染速度快,也不用考慮適配問(wèn)題。
- 圖片壓縮。一般UI給的資源圖都是軟件直接導(dǎo)出的PNG圖片,體積較大??梢园褕D片壓縮后,再放入項(xiàng)目中。推薦使用tinyPNG ,或者AndroidStudio 插件TinyPic 壓縮。
- 使用webp圖片。相同的圖片質(zhì)量下,體積更小。
- webp的無(wú)損壓縮比PNG文件小45%左右
- AndroidStudio 自帶轉(zhuǎn)換功能,可以把png轉(zhuǎn)換為webp。
- 不用考慮Android系統(tǒng)兼容問(wèn)題,因?yàn)槟壳按蟛糠諥pp的最低支持版本都是4.4.4。
- 缺點(diǎn)是解碼速度相對(duì)慢些,在加載網(wǎng)絡(luò)圖片上很有優(yōu)勢(shì)。
- svg矢量圖。其實(shí)是圖片的描述文件,犧牲CPU的計(jì)算能力的,節(jié)省空間。適用于簡(jiǎn)單的圖標(biāo)。
目前WEBP與JPG相比較,編碼速度慢10倍,解碼速度慢1.5倍,雖然會(huì)增加額外的解碼時(shí)間,但是由于減少了文件體積,縮短了加載的時(shí)間,實(shí)際上文件的渲染速度反而變快了。
4.2.1+ 對(duì)于webp的decode、encode是完全支持的(包含半透明的webp圖)
對(duì)于4.0+ 到 4.2.1 ,只支持完全不透明的decode、encode的webp圖
4.0 以下,應(yīng)該是默認(rèn)不支持webp了
資源文件混淆
主要是使用微信開(kāi)源的AndResGuard資源混淆工具。這是個(gè)縮小APK大小的工具,他的原理類似Java Proguard,但是只針對(duì)資源。他會(huì)將原本冗長(zhǎng)的資源路徑變短,例如將res/drawable/wechat變?yōu)閞/d/a。
這個(gè)工具不僅可以混淆資源文件,還利用了7z深度壓縮,進(jìn)一步減少安裝包大小。如何使用請(qǐng)參考 AndResGuard的使用。
實(shí)現(xiàn)的原理是:resource.arsc文件中保存著資源文件夾中各個(gè)資源的路徑。AndResGuard工具將資源文件重命名(甚至修改文件夾名,將drawable改為a0)后,再生成新的resource.arsc文件,替換源文件打包簽名即可。


去除不用so文件
在使用一些三方庫(kù)的時(shí)候,會(huì)集成大量的so文件到項(xiàng)目中,這些so文件都對(duì)應(yīng)著不同的CPU架構(gòu)。
Android系統(tǒng)目前支持以下七種不同的CPU架構(gòu):ARMv5、ARMv7、x86、MIPS、ARMv8、MIPS64、x86_64,每一個(gè)CPU架構(gòu)對(duì)應(yīng)一個(gè)ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。
目前市面上絕大部分的CPU架構(gòu)都是 ARMv7/ARMv8,所以可以在gradle中加入配置,只保留v7,v8。
defaultConfig {
...
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
甚至只保留 armeabi-v7a ,微信大佬就這么干的!
資源動(dòng)態(tài)加載
也可以將一些不必要資源放入網(wǎng)絡(luò)中,等需要時(shí)再下載,比如:
- emoji表情
- 換膚
- 動(dòng)態(tài)添加插件化模塊(插件化框架)
移除無(wú)用資源
可以使用Lint工具檢測(cè)無(wú)用的資源,然后移除掉。
- 點(diǎn)擊菜單“Analyze”
- 選擇 “run inspaction by Name ...”
- 在彈出的搜索窗口中輸入想執(zhí)行的檢查類型,如“Unused Resources”。
- 選擇檢查的范圍,一般選擇整個(gè)項(xiàng)目或模塊。
- 選擇好后點(diǎn)ok就開(kāi)始檢查了。然后就可以根據(jù)檢查結(jié)果來(lái)去除重復(fù)的資源。
如果覺(jué)得一個(gè)個(gè)刪除太麻煩,可以開(kāi)啟代碼混淆,在打包時(shí)排除不需要的資源。
代碼混淆
這個(gè)不用多說(shuō),大家都知道。
- 可以刪除注釋和不用的代碼。
- 將java文件名改成短名a.java,b.java
buildTypes {
release {
buildConfigField "boolean", "LOG_DEBUG", "false" //不顯示log
minifyEnabled true //開(kāi)啟混淆
shrinkResources true //移除無(wú)用資源
zipAlignEnabled true //Zipalign優(yōu)化
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.config
}
}
}