隨著我們的APP迭代,安裝包的體積也會(huì)跟著增大屎慢。
就拿我目前所開(kāi)發(fā)維護(hù)的APP來(lái)講瞭稼,版本號(hào)20,APK大小是10M腻惠,金融類的應(yīng)用环肘。雖然功能也不少,但是因?yàn)槭腔旌祥_(kāi)發(fā)集灌,對(duì)于我這種“斤斤計(jì)較”的人來(lái)說(shuō)悔雹,這個(gè)大小還是偏大的,應(yīng)用太大不利于運(yùn)營(yíng)推廣绝页,并且浪費(fèi)用戶的流量荠商,所以在APP的瘦身是很必要的。這片文章講我的應(yīng)用在APK瘦身中的一些經(jīng)驗(yàn)方法续誉,希望對(duì)你能有所幫助莱没。
APK分析
我們來(lái)看下APK的構(gòu)成,將你編譯后的APK拖到AndroidStudio中酷鸦,從AndroidStudio2.2版本開(kāi)始我們可以使用APK Analyzer來(lái)分析APK饰躲,當(dāng)然你也可以更改APK的后綴名為zip牙咏,解壓之后可以看到APK的內(nèi)容,如下圖:
APK主要由一下幾個(gè)部分組成
res:
主要存放一些圖片資源和xml資源
lib:
存放各種架構(gòu)的so庫(kù)
classes.dex
java源碼編譯后生成的java字節(jié)碼文件嘹裂,由于超過(guò)了Android最大方法數(shù)限制妄壶,這里拆分了多個(gè)dex文件
assets
主要存放一些不需要編譯處理的文件,比如我們常常為了加快WebView的訪問(wèn)速度寄狼,會(huì)把一些框架性不常更改的js丁寄、css和一些png等圖片資源放在這里面
resources.arsc
編譯后的二進(jìn)制資源文件,包括圖片泊愧、文本索引等
META-INF
應(yīng)用簽名信息
AndroidManifest.xml
描述配置文件
從圖片中我們看到占比較大的幾個(gè)伊磺,對(duì)其進(jìn)行分析優(yōu)化。
優(yōu)化方式1-資源優(yōu)化
圖片資源壓縮-res文件夾下
1.TinyPng
可以拖拽圖片到網(wǎng)頁(yè)上處理删咱,同時(shí)提供HTTP api來(lái)處理屑埋,有數(shù)量限制,每個(gè)key每個(gè)月限500張痰滋。網(wǎng)上也有相關(guān)的Gradle插件來(lái)批量處理摘能,我的項(xiàng)目中使用的就是這種圖片壓縮方式,壓縮效果因圖片而異敲街,我的項(xiàng)目中的圖片大小減小了一半左右团搞。Mac下或者安裝了Python環(huán)境的同學(xué)可以試一下這個(gè)批量壓縮的腳本GcsSloop/TinyPng
提供客戶端,未使用過(guò)聪富,具體請(qǐng)移步官網(wǎng)
需要說(shuō)明的是這里的壓縮雖然最大程度的保留了圖片的質(zhì)量莺丑,優(yōu)化修改了png的一些屬性等著蟹,但是對(duì)于圖片質(zhì)量還是有一些影響的墩蔓,特別是在一些高清大圖。
移除無(wú)用資源
有時(shí)候我們移除某一項(xiàng)功能的時(shí)候萧豆,并沒(méi)有移除相應(yīng)的資源文件奸披,如果不做處理,這部分資源文件很有可能打包到我們的apk中涮雷,產(chǎn)生空間浪費(fèi)阵面。
1.使用AndroidStudio自帶的Lint檢查無(wú)用資源,然后通過(guò)腳本批量移除洪鸭;
2.使用Gradle的shrinkResources在打包的時(shí)候移除未使用資源样刷;
3.官方推薦我們?cè)诓煌直媛蕦?duì)應(yīng)的文件夾下放置對(duì)應(yīng)的資源圖片,ldpi mdpi hdpi xhdpi xxhdpi xxxhdp等览爵,但是這樣做的話會(huì)極大的增加包的體積置鼻,一般來(lái)說(shuō)我們只需要兩三套就可以了,我現(xiàn)在是使用的一套圖片資源蜓竹,現(xiàn)階段可以只保留xhdpi下的圖片箕母,關(guān)于為什么官方推薦需要多套資源圖片储藐,請(qǐng)自省百度,這也是個(gè)很重要的知識(shí)點(diǎn)嘶是;
減少多語(yǔ)言支持
我們的APK默認(rèn)打包出來(lái)支持幾十種語(yǔ)言钙勃,這顯然是不必要,我這里只保留簡(jiǎn)體中文聂喇,當(dāng)然如果你的APP在繁體中文或者海外也有推廣運(yùn)營(yíng)的話辖源,請(qǐng)保留需要的語(yǔ)言,這種方式能減少幾百k的大小希太。
defaultConfig {
resConfigs "zh"
}
資源混淆方案
我記得以前剛學(xué)反編譯apk的時(shí)候同木,嘗試反編譯微信的APK,但是反編譯后發(fā)現(xiàn)xml文件都是a跛十、b彤路、c這種命名,覺(jué)得很神奇芥映。后來(lái)才知道洲尊,這是微信自己開(kāi)發(fā)的資源混淆方式,原理是把冗長(zhǎng)的資源路徑變短奈偏。詳情請(qǐng)見(jiàn)AndResGuard坞嘀。通過(guò)這種方式我把APK又減小了0.8M。但是有一點(diǎn)請(qǐng)注意惊来,一些通過(guò)反射獲得的資源或者是某些三方庫(kù)中的資源需要加入白名單丽涩,要多加測(cè)試,避免出錯(cuò)裁蚁。
lib文件夾
1.CPU架構(gòu)支持
Android目前支持的架構(gòu)多達(dá)七種矢渊,每一種架構(gòu)對(duì)應(yīng)一種ABI:armeabi,armeabi-v7a枉证,x86矮男,mips,arm64-v8a室谚,mips64毡鉴,x86_64。所有的x86秒赤、x8664猪瞬、armeabi-v7a、arm64-v8a設(shè)備都支持armeabi架構(gòu)的.so文件入篮,x86設(shè)備能夠很好的運(yùn)行ARM類型函數(shù)庫(kù)陈瘦,但并不保證100%不發(fā)生crash,特別是對(duì)舊設(shè)備崎弃。64位設(shè)備(arm64-v8a, x8664, mips64)能夠運(yùn)行32位的函數(shù)庫(kù)甘晤,但是以32位模式運(yùn)行含潘,在64位平臺(tái)上運(yùn)行32位版本的ART和Android組件,將丟失專為64位優(yōu)化過(guò)的性能(ART线婚,webview遏弱,media等等)。一般的應(yīng)用完全可以根據(jù)自己業(yè)務(wù)需求選擇使用armeabi或者armeabi-v7a一種支持就行塞弊。
ndk {
abiFilters 'armeabi'
}
2.動(dòng)態(tài)下發(fā)
so文件可以通過(guò)動(dòng)態(tài)下發(fā)的方式延遲加載漱逸,網(wǎng)絡(luò)上有文章這么做過(guò),我這里沒(méi)用過(guò)不做說(shuō)明游沿。
dex文件
1.Gradle中設(shè)置minifyEnabled true混淆饰抒、壓縮代碼
2.刪除一些無(wú)用庫(kù),包括一些早期的兼容庫(kù)诀黍,刪除一些非必需的三方庫(kù)袋坑,或使用輕量級(jí)的替代庫(kù)
3.插件化開(kāi)發(fā),通過(guò)下發(fā)的方式減小APP體積
其它方式
1.Proguard不保留行號(hào)信息眯勾,但是這種方式會(huì)不利于我們查找線上bug日志
2.facebook的ReDex枣宫,需要多測(cè)試
... ...
通過(guò)上面的方式,我目前開(kāi)發(fā)的apk大小也從原來(lái)的10M多降到6.5M吃环,效果還是很明顯的也颤,這其中還不包括由于一些原因未采用的方式。
我們常見(jiàn)的APK瘦身方法就講完了郁轻,如果你有更多更好的方式請(qǐng)告訴我翅娶,當(dāng)然,這都是現(xiàn)階段的優(yōu)化方法好唯,隨著Android的進(jìn)步我們肯定會(huì)有更多的方法竭沫。