1妥箕、 前言
如果你對(duì)App優(yōu)化比較敏感,那么Apk安裝包的大小就一定不會(huì)忽視更舞。關(guān)于瘦身的原因畦幢,大概有以下幾個(gè)方面:
- 對(duì)于用戶(hù)來(lái)說(shuō),在功能差別不大的前提下缆蝉,更小的Apk大小意味更少的流量消耗宇葱,也意味著更多的用戶(hù)下載;
- 對(duì)于產(chǎn)品來(lái)說(shuō)刊头,大于競(jìng)品的Apk意味著較低的下載基數(shù)黍瞧,不利于驗(yàn)證產(chǎn)品策略;
- 對(duì)于開(kāi)發(fā)人員來(lái)說(shuō)原杂,App瘦身則是一次技術(shù)優(yōu)化印颤、技術(shù)提升的機(jī)會(huì);
2污尉、 Apk的組成
2.1 Apk典型組成
下表為Apk目錄及文件說(shuō)明:
文件/目錄 | 說(shuō)明 |
---|---|
assets/ | 存放一些靜態(tài)文件膀哲,可以通過(guò)AssertManager訪(fǎng)問(wèn) |
lib/ | 如果該目錄存在,一般存放的是NDK編譯出來(lái)的so |
META-INF/ | 保存著APK的簽名信息 |
res/ | 資源文件所在目錄被碗,包含drawable某宪、layout等 |
AndroidManifest.xml | 程序全局配置文件 |
classes.dex | Java Class,被DEX編譯后可供Dalvik/ART虛擬機(jī)所理解的文件格式 |
resources.arsc | 編譯后生成的二進(jìn)制資源文件 |
2.2 示例分析
做App瘦身之前需要對(duì)自己App現(xiàn)有組成有一個(gè)清晰的認(rèn)識(shí)锐朴,上述解壓的方式只能粗略的看出具體目錄的大小兴喂,但是有用信息仍然有限。
2.2.1 Android Studio Analyze APK
Android Studio 2.2之后有一個(gè)功能Analyze APK焚志,方便簡(jiǎn)單衣迷,功能還是Google自帶的靠譜;
- 查看apk中任意文件的大小酱酬,得到一個(gè)直觀的認(rèn)識(shí)壶谒;
- 了解Dex文件的組成,查看使用那些開(kāi)源庫(kù)等膳沽;
- 查看二進(jìn)制文件(如AndroidMainfest.xml等)汗菜;
- Apk的比較,便于發(fā)現(xiàn)兩個(gè)版本之間的區(qū)別挑社。
2.2.2 反編譯工具ClassyShark
ClassShark 是一款查看Android執(zhí)行文件(apk)的瀏覽工具陨界,可以很方便的打開(kāi)APK/Class/Jar/res等文件和分析里面的內(nèi)容。
2.2.3 Nimbledroid
NimbleDroid 是美國(guó)哥倫比亞大學(xué)的博士創(chuàng)業(yè)團(tuán)隊(duì)研發(fā)出來(lái)的分析Android app性能指標(biāo)的系統(tǒng)痛阻,分析的方式有靜態(tài)和動(dòng)態(tài)兩種方式菌瘪,其中靜態(tài)分析可以分析出APK安裝包中大文件排行榜,各種知名SDK的大小以及占代碼整體的比例阱当,各種類(lèi)型文件的大小以及占排行俏扩,各種知名SDK的方法數(shù)以及占所有dex中方法數(shù)的比例。
總結(jié):這三種方式都可以對(duì)Apk的組成有一個(gè)更加清晰的認(rèn)識(shí)弊添,但更加推薦使用AndroidStudio自帶的Analyze APK动猬,簡(jiǎn)單、高效表箭。
使用Analyze APK查看到文件大小之后發(fā)現(xiàn)赁咙,classes.dex、res免钻、assets彼水、lib等文件較大,哪里的脂肪多极舔,我們就去抽哪里凤覆。確定優(yōu)化方向:
- 代碼部分:冗余代碼、無(wú)用功能拆魏、代碼混淆盯桦、方法數(shù)縮減等慈俯;
- 資源部分:冗余資源、資源混淆拥峦、圖片處理等贴膘;
- 對(duì)So文件的處理等。
3略号、 Apk瘦身之代碼瘦身
3.1 移除無(wú)用代碼刑峡、功能
隨著版本的迭代,部分功能可能已被去掉玄柠,但是其代碼還存在項(xiàng)目中突梦。移除無(wú)用代碼以及無(wú)用功能,有助于減少代碼量羽利,直接體現(xiàn)就是Dex的體積會(huì)變小宫患。
備注:根據(jù)經(jīng)驗(yàn),不用的代碼在項(xiàng)目中存在屬于一個(gè)普遍現(xiàn)象这弧,相當(dāng)于僵尸代碼撮奏,而且這類(lèi)代碼過(guò)多也會(huì)導(dǎo)致Dex文件過(guò)大。
3.2 移除無(wú)用的庫(kù)当宴、避免功能雷同的庫(kù)
3.2.1 項(xiàng)目中基礎(chǔ)功能的庫(kù)要統(tǒng)一實(shí)現(xiàn)畜吊,避免出現(xiàn)多套網(wǎng)絡(luò)請(qǐng)求、圖片加載器等實(shí)現(xiàn)户矢。
3.2.2 不用的庫(kù)要及時(shí)移除出項(xiàng)目玲献,例如我們之前確定要由某推送切換到某推送的時(shí)候,此時(shí)就要把最初項(xiàng)目中的推送庫(kù)去掉梯浪,而不應(yīng)該只是注釋掉其注冊(cè)代碼捌年。
3.2.3 一些功能可以曲線(xiàn)救國(guó)的話(huà)就不要引入SDK,例如定位功能挂洛,可以不引入定位SDK礼预,而通過(guò)拿到經(jīng)緯度然后調(diào)用相關(guān)接口來(lái)實(shí)現(xiàn);同樣實(shí)現(xiàn)了功能而沒(méi)有引入SDK虏劲。
3.2.4 而引入SDK也需要考慮其方法數(shù),可以使用ClassyShark托酸、Nimbledroid或者APK method count等工具查看。
備注:根據(jù)經(jīng)驗(yàn)柒巫,項(xiàng)目中存在之前使用之后不使用的庫(kù)的情況并不罕見(jiàn)励堡。
3.3 啟用Proguard
代碼混淆也稱(chēng)為花指令,是將計(jì)算機(jī)程序的代碼轉(zhuǎn)換為功能上等價(jià)但是難以閱讀堡掏、理解的行為应结。Proguard是一個(gè)免費(fèi)的Java類(lèi)文件壓縮、優(yōu)化、混淆鹅龄、預(yù)先驗(yàn)證的工具揩慕,可以檢測(cè)和移除未使用的類(lèi)、字段扮休、方法迎卤、屬性,優(yōu)化字節(jié)碼并移除未使用的指令肛炮,并將代碼中的類(lèi)止吐、字段宝踪、方法的名字改為簡(jiǎn)短侨糟、無(wú)意義的名字瘩燥。
可以看出Proguard不僅能將diamante中的各種元素改的簡(jiǎn)短秕重,還可以移除冗余代碼,因此可以減少Dex文件的大小厉膀。
android {
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'proguard-rules.pro'
}
}
...
}
其中溶耘,proguard-android.txt是獲取默認(rèn)ProGuard設(shè)置,proguard-rules.pro文件用于添加自定義ProGuard規(guī)則服鹅。
備注:對(duì)于Proguard凳兵,雖然效果很明顯,但仍然需要謹(jǐn)慎企软;
- 代碼混淆會(huì)拖慢項(xiàng)目構(gòu)建速度庐扫,因此debug模式下關(guān)掉Proguard不至于RD在運(yùn)行代碼的時(shí)候抓狂;
- 因?yàn)樵赿ebug模式下關(guān)掉了Proguard仗哨,如果混淆規(guī)則沒(méi)有配置好形庭,在Release模式可能會(huì)出現(xiàn)debug模式下不出現(xiàn)的Bug;
- Proguard也不是你想搞就能搞厌漂,如果App做了一段時(shí)間之后再來(lái)做Proguard萨醒,項(xiàng)目包結(jié)構(gòu)不規(guī)范的話(huà),那Proguard的規(guī)則將會(huì)非常多苇倡。而短時(shí)間內(nèi)調(diào)整包結(jié)構(gòu)也是一件相當(dāng)痛苦的事情富纸。
3.4 縮減方法數(shù)
一般情況下縮減方法數(shù),都是為了Android著名的64k方法數(shù)問(wèn)題旨椒,此處不再回顧胜嗓,參見(jiàn)之前《關(guān)于Multidex的系列文章》。而這里說(shuō)縮減方法數(shù)的目的钩乍,是為了App瘦身辞州。
通過(guò)《Dalvik Executable format》,我們可以看到Dex文件的組成寥粹。而從header-item表中的method-ids-size字段可以看出变过,方法數(shù)縮減之后埃元,可以減少方法列表的大小媚狰;同時(shí)岛杀,方法在Dex文件中的占用空間也減少了,App自然被瘦身崭孤。
而縮減方法數(shù)类嗤,除了上面寫(xiě)到的普遍方法:移除無(wú)用方法、庫(kù)辨宠、使用較小的SDK之外還有:
- 避免在內(nèi)部類(lèi)中訪(fǎng)問(wèn)外部類(lèi)的私有方法遗锣、變量。當(dāng)在Java內(nèi)部類(lèi)(包含匿名內(nèi)部類(lèi))中訪(fǎng)問(wèn)外部類(lèi)的私有方法嗤形、變量的時(shí)候精偿,編譯器會(huì)生成額外的方法,會(huì)增加方法數(shù)赋兵;
- 避免調(diào)用派生類(lèi)中的未被覆寫(xiě)的方法笔咽,避免在派生類(lèi)中調(diào)用未覆寫(xiě)的基類(lèi)的方法;避免用派生類(lèi)的對(duì)象調(diào)用派生類(lèi)中未覆蓋的基類(lèi)的方法霹期。調(diào)用派生類(lèi)中的未被覆蓋的方法時(shí)叶组,會(huì)多產(chǎn)生一個(gè)方法數(shù);
- 去掉部分類(lèi)的get历造、set方法甩十;當(dāng)然這樣會(huì)犧牲一些面向?qū)ο蟮挠^念。
4帕膜、 Apk瘦身之資源瘦身
對(duì)于重要性枣氧,代碼和資源的瘦身同樣重要,但是從效果上來(lái)說(shuō)垮刹,資源文件的瘦身效果比代碼的瘦身效果要好非常多达吞。很有可能費(fèi)力許久在代碼上得到的瘦身效果,在資源文件瘦身中輕松就得到了荒典。
4.1 移除無(wú)用的資源文件
移除無(wú)用資源文件要比移除無(wú)用代碼容易酪劫,在Android Studio的任何文件中右擊,選擇清除無(wú)用資源即可刪除沒(méi)有用到的資源文件寺董。
備注:在build.gradle中設(shè)置shrinkResources為true后覆糟,每次打包的時(shí)候就會(huì)自動(dòng)排除無(wú)用的資源。shrinkResources需要配合minifyEnabled一起使用遮咖。但是根據(jù)我的實(shí)驗(yàn):無(wú)用的資源還是會(huì)被打進(jìn)Apk中滩字,只是變成一張黑圖,體積也非常小,只有不到100b麦箍。有使用錯(cuò)誤的地方歡迎指正漓藕!
4.2 Drawable目錄只保留一份資源
這條開(kāi)發(fā)者中討論的比較多,確實(shí)Google強(qiáng)烈建議根據(jù)不同屏幕密度準(zhǔn)備多套切圖資源來(lái)做適配的挟裂。但是鑒于Android上對(duì)UI要求不會(huì)是最頂級(jí)的那種高度享钞,以及即便是放在合適(注意這兩個(gè)字)一個(gè)的目錄下,在不同的分辨率下也會(huì)做自動(dòng)的適配(等比例拉伸诀蓉、縮放)栗竖;因此還是建議:對(duì)UI不是最頂級(jí)要求的話(huà)根據(jù)自己的用戶(hù)群體機(jī)型放在一個(gè)合適的目錄下。這樣毋庸置疑可以縮減Res的大小渠啤,進(jìn)而減少Apk的體積狐肢。
備注:圖片放在不恰當(dāng)?shù)哪夸浻锌赡軙?huì)對(duì)內(nèi)存產(chǎn)生較大的影響,可以參考之前的文章《Android 性能優(yōu)化(五)之細(xì)說(shuō) Bitmap》埃篓。
4.3 對(duì)圖片進(jìn)行壓縮
之前我在項(xiàng)目里發(fā)現(xiàn)過(guò)文件大小過(guò)1M的圖片处坪,可能是由于UI同學(xué)和RD同學(xué)的雙重疏忽根资,導(dǎo)致如此大的圖片到了項(xiàng)目中架专,對(duì)Apk體積的影響自然不言而喻。
可以考慮使用TinyPng玄帕、pngquant部脚、ImageOptim等工具對(duì)圖片進(jìn)行壓縮,這些工具可以減少PNG文件大小裤纹,同時(shí)保持圖像質(zhì)量委刘。
此處以TinyPng為例:TinyPng是一個(gè)相當(dāng)不錯(cuò)的圖片壓縮工具,在保持alpha通道的情況下對(duì)PNG的壓縮可以達(dá)到1/3之內(nèi)鹰椒,而且用肉眼基本上分辨不出壓縮的損失锡移。這張3.4M的圖片被壓縮到了984.7k,壓縮率高達(dá)71%漆际。
也有同學(xué)開(kāi)發(fā)了一個(gè)AndroidStudio插件:TinyPngPlugin淆珊,能夠批量地壓縮項(xiàng)目中的圖片,更加方便奸汇。
備注:需要注意的是在Android構(gòu)建流程中AAPT會(huì)使用內(nèi)置的壓縮算法來(lái)優(yōu)化res/drawable/目錄下的PNG圖片施符,但也可能會(huì)導(dǎo)致本來(lái)已經(jīng)優(yōu)化過(guò)的圖片體積變大,可以通過(guò)在build.gradle中設(shè)置cruncherEnabled來(lái)禁止AAPT采用默認(rèn)方式優(yōu)化我們已經(jīng)優(yōu)化過(guò)的圖片擂找。
aaptOptions {
cruncherEnabled = false
}
4.4 PNG轉(zhuǎn)換JPG
PNG是一種無(wú)損格式戳吝,JPG是有損格式。JPG在處理顏色很多的圖片時(shí)贯涎,根據(jù)壓縮率的不同听哭,有時(shí)會(huì)去掉一些肉眼識(shí)別差距較小的中間顏色。但是PNG對(duì)于無(wú)損這個(gè)基本要求,會(huì)嚴(yán)格保留所有的色彩數(shù)陆盘。所以圖片尺寸大且警,或者色彩數(shù)量多特別是漸變色的多的時(shí)候,PNG的體積會(huì)明顯大于JPG礁遣。
在這種情況下斑芜,我們可以有所取舍。小尺寸祟霍、色彩較少或者有alpha通道透明度的時(shí)候杏头,使用PNG;大尺寸沸呐、色彩漸變多的使用JPG醇王。
備注:根據(jù)經(jīng)驗(yàn),對(duì)于可以直接使用JPG格式的圖片崭添,最好不要從PNG轉(zhuǎn)換為JPG寓娩,而是出圖的時(shí)候直接出JPG格式的圖片,相對(duì)而言呼渣,后者的效果更好棘伴。
4.5 使用矢量圖
可縮放矢量圖形(英語(yǔ):Scalable Vector Graphics,SVG)是一種基于可擴(kuò)展標(biāo)記語(yǔ)言(XML)屁置,用于描述二維矢量圖形的圖形格式焊夸。SVG由W3C制定,是一個(gè)開(kāi)放標(biāo)準(zhǔn)蓝角≮逅耄可以使用矢量圖形來(lái)創(chuàng)建獨(dú)立于分辨率的圖標(biāo)和其他可伸縮圖片。使用矢量圖片能夠有效的減少App中圖片所占用的大小使鹅,矢量圖形在Android中表示為VectorDrawable對(duì)象揪阶。
優(yōu)點(diǎn)
- 圖片擴(kuò)展性:不損傷圖片質(zhì)量,一套圖適配所有患朱;
- 圖片非常新沉拧:比使用位圖小十幾倍,有利于減小apk體積麦乞;
缺點(diǎn)
- 性能優(yōu)損失蕴茴,系統(tǒng)渲染VectorDrawable需要花費(fèi)更多時(shí)間,因?yàn)槭噶繄D的初始化加載會(huì)比相應(yīng)的光柵圖片消耗更多的CPU周期姐直,但是兩者之間的內(nèi)存消耗和性能接近倦淀;
- 矢量圖主要用在色調(diào)單一的icon。
4.6 使用WebP
Google于2010年提出了一種新的圖片壓縮格式 — WebP声畏,為圖片提供了無(wú)損和有損壓縮能力撞叽,同時(shí)在有損條件下支持透明通道姻成。據(jù)官方實(shí)驗(yàn)顯示:無(wú)損WebP相比PNG減少26%大小愿棋;有損WebP在相同的SSIM(Structural Similarity Index科展,結(jié)構(gòu)相似性)下相比JPEG減少25%~34%的大小糠雨;有損WebP也支持透明通道才睹,大小通常約為對(duì)應(yīng)PNG的1/3。同時(shí)甘邀,谷歌于2014年提出了動(dòng)態(tài)WebP琅攘,拓展WebP使其支持動(dòng)圖能力。動(dòng)態(tài)WebP相比GIF支持更豐富的色彩松邪,并且也占用更小空間坞琴,更適應(yīng)移動(dòng)網(wǎng)絡(luò)的動(dòng)圖播放。
優(yōu)點(diǎn):
- WebP在同畫(huà)質(zhì)下體積更小逗抑,WebP支持透明度剧辐,壓縮比比JPEG更高但顯示效果卻不輸于JPEG;
- 可以通過(guò)工具邮府、云服務(wù)等進(jìn)行PNG到WebP的轉(zhuǎn)換荧关;
缺點(diǎn):
- Android從4.0才開(kāi)始WebP的原生支持,意味著要兼容4.0以下機(jī)型需要添加適配庫(kù)挟纱;當(dāng)然現(xiàn)在市面上適配4.0以下的應(yīng)用已經(jīng)很少了羞酗。
- Android 4.2.1+才支持顯示含透明度的WebP腐宋,因此最低版本小于4.2.1的App也不是想用就能用的紊服。可以將不顯示透明度的圖片轉(zhuǎn)換為WebP胸竞。
4.7 資源混淆
在Apk打包過(guò)程中欺嗤,aapt會(huì)將每一個(gè)資源生成一個(gè)對(duì)應(yīng)的int數(shù)值,而我們通過(guò)這個(gè)int值來(lái)查找使用資源卫枝。在Apk構(gòu)成中煎饼,我們可以看到里面有一個(gè)resources.arsc文件,里面保存著資源id和資源key的映射關(guān)系校赤。
當(dāng)調(diào)用圖片時(shí)吆玖,先找到drawable分類(lèi),再根據(jù)當(dāng)前的系統(tǒng)config找到匹配的config表马篮,根據(jù)id找到對(duì)應(yīng)的res數(shù)據(jù)沾乘。drawable在arsc中是當(dāng)做string類(lèi)型保存的,res數(shù)據(jù)中有這個(gè)資源在res string pool池中的索引浑测。根據(jù)這個(gè)索引可以在字符串池中找到一個(gè)字符串翅阵。這個(gè)字符串其實(shí)就是一個(gè)路徑歪玲,比如:res/drawable-xhdpi/icon.png;混淆就是將這個(gè)路徑改為R/s/f.png掷匠;同時(shí)修改resources.arsc文件的映射關(guān)系滥崩。這樣就能清楚的看出來(lái)資源混淆能減小Apk的原因:
- resources.arsc變小讹语;
- 文件信息變小钙皮,采用了超短路徑,res/drawable-xhdpi/icon.png被修改為R/s/f.png顽决。
這里推薦微信的資源混淆方案:AndResGuard株灸。
4.8 資源在線(xiàn)化
將部分使用頻率不高的資源例如圖片,放在網(wǎng)上擎值,在恰當(dāng)?shù)臅r(shí)機(jī)提前下載慌烧,這樣也能節(jié)約部分空間。
5鸠儿、 Apk瘦身之So瘦身
So(shared object屹蚊,共享庫(kù))是機(jī)器可以直接運(yùn)行的二進(jìn)制代碼,是Android上的動(dòng)態(tài)鏈接庫(kù)进每,類(lèi)似于Windows上的dll汹粤。每一個(gè)Android應(yīng)用所支持的ABI是由其APK提供的.so文件決定的,這些so文件被打包在apk文件的lib/目錄下田晚。
So的常見(jiàn)的場(chǎng)景如:加解密算法嘱兼、音視頻編解碼、核心代碼等贤徒。在生成SO文件時(shí)芹壕,需要考慮適配市面上不同手機(jī)CPU架構(gòu),而生成支持不同平臺(tái)的SO文件進(jìn)行兼容接奈。目前Android共支持七種不同類(lèi)型的CPU架構(gòu)踢涌,分別是:ARMv5,ARMv7 (從2010年起)序宦,x86 (從2011年起)睁壁,Mips (從2012年起),ARMv8互捌,Mips64和x86_64 (從2014年起)潘明。
理論上對(duì)應(yīng)CPU架構(gòu)的So的執(zhí)行效率是最高的,但是這樣會(huì)導(dǎo)致在libs目錄下放置各個(gè)架構(gòu)平臺(tái)的So文件秕噪,Apk文件的大小自然也就更大了钳降。那么我們自然想到縮減Libs的目錄,一般情況(注意限定)下留下armeabi目錄即可巢价,armeabi目錄下的So可以兼容別的平臺(tái)的So牲阁,但是性能會(huì)有所損耗固阁,失去對(duì)特定平臺(tái)的優(yōu)化。
因此需要根據(jù)自己使用到的So功能來(lái)做具體的區(qū)分:對(duì)于性能敏感模塊使用的So可以都放在armeabi目錄城菊,然后通過(guò)代碼判斷設(shè)備的CPU類(lèi)型备燃,再加載其對(duì)應(yīng)架構(gòu)的SO文件,例如微信就是這么做的凌唬。既縮減了Apk的體積并齐,也不影響性能敏感模塊的執(zhí)行。
移除特定平臺(tái)So的方式客税,這樣打包就只保存armeabi里的So况褪。
ndk {
//設(shè)置支持的SO庫(kù)架構(gòu)
abiFilters 'armeabi'
}
備注:原本x86架構(gòu)的CPU是不支持運(yùn)行arm架構(gòu)的So,但I(xiàn)ntel和Google合作在x86機(jī)子的系統(tǒng)內(nèi)核層之上加入了一個(gè)名為houdini的Binary Translator(二進(jìn)制轉(zhuǎn)換中間層)更耻,這個(gè)中間層會(huì)在運(yùn)行期間動(dòng)態(tài)的讀取arm指令并將之轉(zhuǎn)換為x86指令去執(zhí)行测垛。
6、 Apk瘦身之7Zip壓縮
我們知道Apk文件實(shí)際上就是一個(gè)Zip文件秧均。Android SDK的打包工具apkbuilder采用的是Deflate算法將Android App的代碼食侮、資源等文件進(jìn)行壓縮,壓縮成Zip格式目胡,然后簽名發(fā)布锯七。
既然是壓縮,那能不能改進(jìn)其壓縮方式誉己,獲取更小的Apk文件眉尸?通過(guò)分析Apk打包的流程圖我們可以發(fā)現(xiàn)SignedJarBuilder類(lèi)對(duì)整個(gè)工程包括代碼Dex和一些課壓縮的資源、文件進(jìn)行壓縮巨双,使用的是JDK中zip包下提供的算法噪猾。
簡(jiǎn)單的方式我們可以在不改變App編譯器工作的情況下虚缎,對(duì)生成的Apk文件進(jìn)行二次壓縮蝎宇,同樣使用Deflate算法,但是將壓縮等級(jí)從標(biāo)準(zhǔn)提升到極限壓縮。提高壓縮級(jí)別可在不對(duì)Apk包本身的內(nèi)容做任何修改的情況下得到更小的Apk疼阔。
備注:
- 需要注意這樣極限壓縮之后的簽名被破壞,需要重新簽名半夷。
- Android平臺(tái)對(duì)Apk安裝包的解壓算法只支持Deflate算法婆廊,其它算法如LZMA,雖然壓縮率更好巫橄,但是由于Android平臺(tái)默認(rèn)不支持淘邻,所以如果采用這種算法壓縮Apk,會(huì)導(dǎo)致Apk無(wú)法安裝湘换。
- 目前在Mac上沒(méi)發(fā)現(xiàn)好用的7Zip壓縮軟件宾舅,需要在Windows下使用统阿。
7、 App瘦身總結(jié):
7.1 代碼瘦身
- 移除無(wú)用代碼筹我、功能扶平;
- 移除無(wú)用的庫(kù)、避免功能雷同的庫(kù)蔬蕊;
- 啟用Proguard结澄;
- 縮減方法數(shù);
7.2 資源瘦身
- 移除無(wú)用的資源文件岸夯;
- Drawable目錄只保留一份資源麻献;
- 對(duì)圖片進(jìn)行壓縮;
- PNG轉(zhuǎn)換JPG猜扮;
- 使用矢量圖勉吻;
- 使用WebP;
- 資源混淆旅赢;
- 資源在線(xiàn)化餐曼;
7.3 So瘦身
- 在允許的情況下,針對(duì)用戶(hù)機(jī)型分布保留特定架構(gòu)的So鲜漩;
7.4 7Zip壓縮
使用7Zip對(duì)Apk進(jìn)行極限壓縮源譬。
7.5 其它
- 類(lèi)如插件化,將Dex與資源文件放在服務(wù)端孕似,需要時(shí)下載踩娘;但是插件化實(shí)施以及與現(xiàn)有項(xiàng)目結(jié)合難度不小,也超出本文主題喉祭,不細(xì)說(shuō)养渴;
- 通過(guò)在 build.gradle配置include來(lái)針對(duì)每個(gè)CPU架構(gòu)生成單獨(dú)的安裝包,按照架構(gòu)上傳Apk泛烙;但是這個(gè)方案在國(guó)內(nèi)應(yīng)用市場(chǎng)幾乎沒(méi)有采用的理卑,只能在Google Play上使用。
- 一點(diǎn)經(jīng)驗(yàn):對(duì)Apk進(jìn)行瘦身蔽氨,瘦身So以及資源文件是見(jiàn)效最快的操作藐唠。瘦身So以及刪除不用的圖片、壓縮圖片之后鹉究,Apk會(huì)縮減很大的比例宇立;而針對(duì)Dex的優(yōu)化可能作用不會(huì)很明顯。
參考:
- Android性能優(yōu)化典范《Smaller APKs : A checklist 》
- 《移動(dòng)App性能評(píng)測(cè)與優(yōu)化》
- 《Android使用矢量圖(SVG, VectorDrawable)實(shí)踐篇》
- 《WebP原理和Android支持現(xiàn)狀介紹》
- 《談?wù)凙ndroid的so》
- 《Android SO文件的兼容和適配》
歡迎關(guān)注微信公眾號(hào):定期分享Java自赔、Android干貨妈嘹!