最近幾周一直在研究如何為APK瘦身烛卧,折騰了很久,是時(shí)候?qū)懫┛涂偨Y(jié)一下了妓局,雖然已經(jīng)準(zhǔn)備了下周一要在客戶端周會(huì)分享用的PPT:APK瘦身探索总放。
價(jià)值
雖然說(shuō)APK瘦身對(duì)于Android對(duì)應(yīng)用可分配內(nèi)存的限制影響不大,但是還是有一些影響的好爬,就以圖片
為例局雄,將一些小圖標(biāo)替換為iconfont能有效減小內(nèi)存的分配,防止OOM的出現(xiàn)存炮。
另外炬搭,無(wú)論是iOS開發(fā)者還是Android開發(fā)者都應(yīng)該嘗試最好學(xué)會(huì)如何為IPA或APK瘦身,不僅僅是為了幫助用戶省流量穆桂、減少下載時(shí)間宫盔、減少占用的存儲(chǔ)空間等等,更重要的是為了提高轉(zhuǎn)化率(注意:本文的轉(zhuǎn)化率均指下載轉(zhuǎn)化率)享完。
那轉(zhuǎn)化率是什么呢灼芭?
舉個(gè)栗子:你的應(yīng)用大小是 18MB ,有100個(gè)潛在用戶想要去下載嘗試使用般又,結(jié)果有20個(gè)用戶嫌棄安裝包太大直接揚(yáng)長(zhǎng)而去彼绷,有20個(gè)用戶在等待下載的過(guò)程中取消下載,最終只有60個(gè)用戶真正下載安裝茴迁,那么應(yīng)用的轉(zhuǎn)化率就是 60/100 = 60% 寄悯。
那為什么要提高轉(zhuǎn)化率呢?
因?yàn)橛脩粼诩m結(jié)下載你的產(chǎn)品還是你的競(jìng)品的時(shí)候堕义,往往會(huì)選擇那個(gè)體驗(yàn)最好猜旬、功能最多、性能最好倦卖、包最小的洒擦。
工具
如何有條理的為APK瘦身,必須知道APK的目錄結(jié)構(gòu)糖耸,不過(guò)在講述這個(gè)之前,我這里先介紹幾個(gè)工具丘薛,在后文會(huì)用到嘉竟。
AndroidStudio2.2.3
AndroidStudio升級(jí)到版本2.2.3之后提供了Analyze APK的功能(不過(guò)作為AS粉想必已經(jīng)升到AS2.3了吧,哈哈),我們可以借助該工具清楚的了解APK的下載大小舍扰、解壓之后的大小倦蚪、內(nèi)部各個(gè)文件夾或文件占用的大小等信息,進(jìn)而得知那些地方可以優(yōu)化边苹。下圖為目前我司測(cè)試版APK的內(nèi)部信息:
另外使用該工具還可以反編譯資源文件陵且、還原layout中的資源id,分析DEX个束、顯示每一個(gè)文件夾或文件的方法數(shù)慕购,分析哪些第三方庫(kù)方法數(shù)很多但實(shí)際只用到了一部分等其他功能。
最后如何使用該工具茬底?有以下兩種方式:
- 直接將APK拖拽進(jìn)入AndroidStudio即可
- 點(diǎn)擊菜單欄Build-Analyze APK...選項(xiàng)沪悲,再選擇需要分析的APK即可
NimbleDroid
NimbleDroid 是美國(guó)哥倫比亞大學(xué)的博士創(chuàng)業(yè)團(tuán)隊(duì)研發(fā)出來(lái)的自動(dòng)化分析Android app性能指標(biāo)的系統(tǒng),分析的方式有靜態(tài)和動(dòng)態(tài)兩種方式:
其中靜態(tài)分析可以分析出APK安裝包中大文件排行榜阱表,各種知名SDK的大小以及占代碼整體的比例殿如,各種類型文件的大小以及占排行,各種知名SDK的方法數(shù)以及占所有dex中方法數(shù)的比例,針對(duì)緩慢的方法最爬,緩慢的第三方SDK和內(nèi)存泄漏涉馁。
其中動(dòng)態(tài)分析可以測(cè)量生成的速度、網(wǎng)絡(luò)爱致、內(nèi)存和磁盤使用率烤送。
我用了一下上面這個(gè)工具,感覺還是不錯(cuò)的蒜鸡,下面我們來(lái)看幾張有逼格的圖(圖中數(shù)據(jù)來(lái)自于我司測(cè)試版APK):
APK內(nèi)部各類型對(duì)應(yīng)文件占用的大小
APK內(nèi)部各個(gè)類庫(kù)的方法數(shù)
APK啟動(dòng)過(guò)程中各個(gè)方法的執(zhí)行時(shí)間
ClassShark
ClassShark 是一款查看Android執(zhí)行文件(apk)的瀏覽工具胯努,目前有兩個(gè)android App(Apk)和桌面(jar)的版本。
使用這款工具逢防,可以很方便的打開APK叶沛、Class、Jar忘朝、res等文件和分析里面的內(nèi)容灰署。
不過(guò)目前這個(gè)工具并不需要我們單獨(dú)使用,因?yàn)锳S內(nèi)部的分析工具就是用的這個(gè)局嘁。
通過(guò)以上工具溉箕,我們可以方便快速的分析APK,找出那些可以優(yōu)化的部分悦昵,為了更加有條理的進(jìn)行講解肴茄,下面我會(huì)按照APK的目錄結(jié)構(gòu)來(lái)逐條闡述。
APK目錄結(jié)構(gòu)
上述表格左邊部分是APK內(nèi)部默認(rèn)存在的文件夾或文件但指,表格右邊對(duì)于各個(gè)文件夾或文件進(jìn)行了簡(jiǎn)要的概述寡痰,詳細(xì)的說(shuō)明會(huì)在之后根據(jù)左邊的順序一一講解抗楔。
assets目錄
assets目錄用于存放需要打包到應(yīng)用程序的靜態(tài)文件,它包含以下幾個(gè)特性:
使用AssetManager類管理資源
assets目錄內(nèi)部文件不會(huì)被系統(tǒng)編譯
assets目錄支持任意深度的子目錄
-
獲取資源需要使用/assets開始(不包含它)的相對(duì)路徑名拦坠,具體代碼如下所示:
String fileNames[] = context.getAssets().list(path);
那么连躏,assets目錄下都可以放什么文件呢?
說(shuō)實(shí)在的贞滨,assets目錄可以存放各種文件入热,不過(guò)正常情況下,一般只存放以下幾種文件:字體文件晓铆、WEB頁(yè)面勺良、配置文件、某些圖片尤蒿。
上述幾種文件除了配置文件之外郑气,我們都可以進(jìn)行適當(dāng)?shù)膲嚎s處理:
字體文件
:可以使用字體資源文件編輯神器Glyphs進(jìn)行壓縮,其壓縮方式其實(shí)就是通過(guò)刪除不需要的字符從而減少APK的大小腰池。
WEB頁(yè)面
:可以考慮使用7zip壓縮工具對(duì)該文件進(jìn)行壓縮尾组,在正式使用的時(shí)候解壓
某些圖片
:可以使用tinypng進(jìn)行圖片壓縮, 目前tinypng已經(jīng)支持png和jpg圖片示弓、.9圖的壓縮
lib目錄
lib目錄用于存放通過(guò)C或C++編寫編譯生成的so文件(native庫(kù)/JNI開發(fā))讳侨,其基本目錄結(jié)構(gòu)如下圖所示:
因?yàn)槟壳笆袌?chǎng)上主流的架構(gòu)還只是arm架構(gòu),所以如果不是必要的話奏属,可以考慮不支持x86和mips架構(gòu)跨跨,但這并不意味著CPU是x86或mips架構(gòu)的手機(jī)就不能正常安裝使用APK了,因?yàn)榉旁赼rm目錄下的so庫(kù)是可以兼容到其他架構(gòu)的囱皿;
另外arm架構(gòu)中的eabi-v7a相比于eabi只是在圖形渲染方面有了很大的改進(jìn)勇婴,所以如果so庫(kù)對(duì)圖形渲染沒(méi)有很高的要求的話,完全可以把so庫(kù)只存放在arm eabi目錄中嘱腥,這樣可以大大減小APK的體積耕渴。
上面的說(shuō)明可能比較籠統(tǒng),下面就拿淘寶齿兔、微信的APK來(lái)說(shuō)明一下:
可以看出淘寶和微信也是這樣處理橱脸,所以我們其實(shí)也可以這樣操作。
res目錄
res目錄用于存放應(yīng)用程序的資源文件分苇,主要包括布局文件添诉、圖片、XML配置文件等医寿,它包含以下幾個(gè)特性:
- 使用Resources類管理資源
- res目錄內(nèi)部文件會(huì)被系統(tǒng)編譯
- res目錄不支持任意深度的子目錄
- 獲取資源不需要通過(guò)相對(duì)路徑找尋栏赴,因?yàn)槲募?huì)被系統(tǒng)編譯,所以需要通過(guò)資源ID(注:資源ID被存放在resources.arsc文件中)查找
其基本目錄結(jié)構(gòu)如下圖所示:
上圖比較全面的列舉了res目錄下經(jīng)常包含的子目錄和文件靖秩,并解釋了各個(gè)子目錄或文件的含義须眷。
根據(jù)上圖我們顯然可以發(fā)現(xiàn)乌叶,res目錄就是我們APK瘦身里面的一大重要部分了,由于其包含的知識(shí)很大柒爸,下面我會(huì)分章節(jié)進(jìn)行闡述,盡量一一闡述清楚事扭。
只用一套圖
首先我給出這么一個(gè)結(jié)論:一個(gè)APK盡量只用一套圖片捎稚,從內(nèi)存占用和適配的角度考慮,建議放在xhdpi文件夾下求橄。
那么為什么要把圖片放在xhdpi文件夾下面呢今野?
由于此處知識(shí)涉及到Android屏幕適配方面的知識(shí),比較復(fù)雜罐农。本文是關(guān)于APK瘦身的条霜,所以就不詳細(xì)講解了。下面進(jìn)行必要的闡述涵亏,首先讓我們來(lái)看兩張圖:
從上面兩張圖我們可以得到以下兩點(diǎn)信息:
- Android主要的設(shè)備分辨率為:1280*720宰睡、1920*1080
- iOS主要的設(shè)備分辨率為:1334*750、2208*1242气筋、1136*640
可能有人要問(wèn)了拆内,得到這兩點(diǎn)信息有什么用?
恩宠默,單單這樣看并不能知道什么麸恍,為了幫助大家了解,我繪制了下面這樣表格搀矫。不過(guò)在展示表格之前抹沪,我先為大家灌輸兩個(gè)知識(shí)點(diǎn):
1、ppi計(jì)算公式
2瓤球、在Android設(shè)備中融欧,dpi 等價(jià)于 ppi
恩,此處請(qǐng)停留10秒......下面展示我繪制的表格:
有兩個(gè)注意點(diǎn):
- 表格中上兩行代表的是Android的設(shè)備分辨率及相關(guān)數(shù)據(jù)冰垄,下三行代表的是iOS的設(shè)備分辨率及相關(guān)數(shù)據(jù)
- Android屏幕密度為320或480是由谷歌規(guī)定的蹬癌,當(dāng)然這里排除各大廠商自行修改的情況
根據(jù)上述表格我們可以清楚的知道iOS流行的設(shè)備分辨率正好對(duì)應(yīng)Android流行的設(shè)備分辨率,那么知道這又有什么用虹茶?
除了一開始給出結(jié)論的內(nèi)存和適配因素外逝薪,更重要的是可以節(jié)省設(shè)計(jì)資源和工作量。在現(xiàn)在的App開發(fā)中(iOS和Android)蝴罪,有些設(shè)計(jì)師為了保持iOS和Android的體驗(yàn)交互一致董济,可能會(huì)以iPhone手機(jī)為基礎(chǔ)進(jìn)行設(shè)計(jì),包括后期的切圖之類的要门。
不過(guò)根據(jù)上述表格虏肾,我們不是應(yīng)該使用兩套圖嗎廓啊?這里由于在Android設(shè)備中xhdpi和xxhdpi目錄下的圖片顯示效果差異不大,所以完全可以只使用一套圖封豪。
現(xiàn)在我們的設(shè)備中只有一套圖了谴轮,接下來(lái)該怎么為APK瘦身呢?
處理圖片
當(dāng)我們從設(shè)計(jì)師手中得到設(shè)計(jì)稿之后吹埠,之后的工作顯然就是切圖了第步,如果設(shè)計(jì)師切好圖就更好了,得到圖片之后我們一定要記得壓縮
缘琅。
如果圖片類型是.png或.jpg的話粘都,我們可以使用tinypng進(jìn)行壓縮;如果圖片類型是.gif的話刷袍,我建議使用PS進(jìn)行壓縮或裁剪翩隧,如果你不會(huì)PS的話,可以讓設(shè)計(jì)師幫忙呻纹。
如果你對(duì)圖片壓縮質(zhì)量不滿意的話堆生,還可以考慮使用不帶alpha值的jpg圖片、9Patch圖片雷酪、同等質(zhì)量下文件更小的WebP圖片格式顽频、或者使用SVG替換某些圖片資源等其他方式。
下面對(duì)于最后兩種方式進(jìn)行簡(jiǎn)要的闡述:
首先是WebP
:AndroidStudio自2.3版本之后提供了Convert to WebP的功能太闺,選中res目錄后右擊滑到底部即可看到此功能糯景,下面的引用講述了WebP的概念和支持度:
WebP是Google新推出的影像技術(shù),它可讓網(wǎng)頁(yè)圖檔有效進(jìn)行壓縮省骂,同時(shí)在質(zhì)量相同的情況下蟀淮,WebP格式圖像的體積要比JPEG格式圖像小40%,進(jìn)而讓整體網(wǎng)頁(yè)下載速度加快钞澳。為了改善JPEG的圖片壓縮技術(shù)怠惶,他們使用了一種基于VP8編碼的圖片壓縮器,利用預(yù)測(cè)編碼技術(shù)轧粟,同時(shí)還采用了一種基于RIFF的非常輕量級(jí)的容器策治。這種容器只會(huì)給每張圖片增加20字節(jié),但能讓圖片作者保存他們想要存儲(chǔ)的元數(shù)據(jù)兰吟。
android同樣作為google的產(chǎn)品通惫,minsdk為4.0即api14以上就可以支持webp,但是對(duì)透明的圖片會(huì)存在一些問(wèn)題混蔼,minsdk為4.2.1+即api17可以完美支持webp履腋。
考慮目前市場(chǎng)4.2.1以下的手機(jī)占比已經(jīng)非常稀少,采用webp格式代替jpg、png的方案非匙窈可行悔政。
下面展示一下我司某張圖片png形勢(shì)下和WebP形勢(shì)下各自的大小:
其次是SVG
:SVG是可縮放矢量圖形(Scalable Vector Graphics)延旧,它使用XML格式定義圖像谋国,可用于替換APK中的圖標(biāo)。
我們開發(fā)者不需要會(huì)如何制作迁沫,這是設(shè)計(jì)師的工作烹卒,當(dāng)然設(shè)計(jì)師也不會(huì)傻乎乎通過(guò)寫代碼的方式繪制圖標(biāo),顯然是使用軟件制作的弯洗。
目前我司也使用了SVG,不過(guò)它的表現(xiàn)形式是阿里巴巴提供的iconfont逢勾,它不僅允許設(shè)計(jì)師自己制作SVG圖片上傳牡整,也提供了百萬(wàn)種圖標(biāo)供選擇。
減少資源
經(jīng)過(guò)上述的方式處理圖片溺拱,想必在圖片質(zhì)量方面已經(jīng)無(wú)計(jì)可施了逃贝,所以我們只能通過(guò)刪除無(wú)用圖片的方式來(lái)為APK瘦身了,當(dāng)然接下來(lái)要介紹的兩種方式可不僅僅是減少圖片迫摔,應(yīng)該稱之為減少資源
沐扳。
這里有個(gè)問(wèn)題:為什么會(huì)出現(xiàn)無(wú)用的資源呢?我認(rèn)為有以下幾種情況:
- 由于多人協(xié)作開發(fā)句占,沒(méi)有好的規(guī)范沪摄,導(dǎo)致個(gè)人思維嚴(yán)重,隨便添加或刪除資源
- 目前公司有好的規(guī)范纱烘,但之前沒(méi)有杨拐,歷史遺留問(wèn)題,沒(méi)人愿意去管理
- 上一版需要該資源擂啥,下一版不需要哄陶,然后沒(méi)有刪除
那么,既然知道了原因哺壶,就應(yīng)該想出辦法去解決屋吨,首先是最簡(jiǎn)單的辦法,我們只需要在主模塊的gradle文件中配置shrinkResources
即可山宾,具體配置方法如下圖所示:
這就是為什么說(shuō)它是最簡(jiǎn)單的減少資源方法的原因至扰。
當(dāng)然,因?yàn)楹?jiǎn)單必然存在缺陷资锰,因?yàn)樗荒軓拇虬膽?yīng)用程序和第三方代碼庫(kù)中刪除未被引用的資源渊胸。如果在不同的資源文件夾下面有同名的資源文件,那么就沒(méi)有辦法刪除了台妆,即使該資源真的沒(méi)有被使用翎猛。
所以胖翰,沒(méi)有好的辦法了,目前我能想到的只能是手動(dòng)刪除了切厘,我們可以通過(guò)AndroidStudio提供的Remove Unused Resources功能預(yù)覽刪除真正未使用的資源萨咳,選中res目錄右擊選擇Refactor-Remove Unused Resources...選項(xiàng)之后會(huì)出現(xiàn)下面這樣的圖:
然后根據(jù)查找到結(jié)果,逐條雙擊打開文件疫稿,按快捷鍵fn+option+F7進(jìn)行查找培他,然后在分析是否應(yīng)該刪除,注意:此處定要慎重遗座,務(wù)必自測(cè)R荨!途蒋!猛遍。
另外,我們還可以通過(guò)將某些圖片轉(zhuǎn)換網(wǎng)絡(luò)圖片的方式解決号坡,但是這個(gè)操作也是需要慎重的懊烤,最重要的一點(diǎn)是不能影響用戶的體驗(yàn)。這邊路飛同學(xué)制作了一個(gè)Chrome插件來(lái)幫助我們快速上傳圖片到cdn中宽堆,可以通過(guò)此處下載:joyuploader腌紧。
最后,還有一種辦法:使用AndroidStudio提供的Lint工具對(duì)工程做靜態(tài)代碼檢查畜隶,它不僅可以找出我們?cè)诖a編寫上面的失誤壁肋,還能夠列出那些未被使用的資源,甚至還可以指出哪些地方可能存在內(nèi)存泄漏等等籽慢,功能非常龐大墩划,所以如果工程較大的話,還是比較耗時(shí)的嗡综,當(dāng)然這并不是問(wèn)題乙帮,因?yàn)槲覀兛梢葬槍?duì)某個(gè)模塊執(zhí)行靜態(tài)代碼檢查。我們可以通過(guò)選中菜單欄Analyze-Inspect Code...選項(xiàng)執(zhí)行靜態(tài)代碼檢查极景,執(zhí)行完成的效果圖如下所示:
資源混淆
目前我們不僅在資源(特指圖片)質(zhì)量方面做到了極致察净,在資源數(shù)量方面也做到了極致,看起來(lái)真的到極致了盼樟。其實(shí)不然氢卡,我們還可以使用資源混淆的方式為APK瘦身,通過(guò)壓縮文件內(nèi)容晨缴,減少文件名長(zhǎng)度的方式實(shí)現(xiàn)译秦。
目前比較出名的資源混淆方式是微信的AndResGuard和美團(tuán)的修改AAPT,不過(guò)由于美團(tuán)的資源混淆方法非常麻煩,還有如果需要通過(guò)getIdentifier
的方式獲取資源時(shí)需要保證這些資源的名字不被混淆筑悴,美團(tuán)很難實(shí)現(xiàn)们拙,所以目前大家都在用微信的資源混淆方式,因?yàn)槲⑿攀褂梅奖愀罅撸姨峁┝税酌麊巍?/p>
下面是我司測(cè)試版APK未使用微信資源混淆和使用了微信資源混淆的差異:
可以清楚的看到砚婆,在使用了微信資源混淆之后,APK減少了0.7MB左右突勇,效果還是十分明顯的装盯。
那么為什么使用了微信資源混淆之后可以實(shí)現(xiàn)APK瘦身呢?下面這兩張圖清楚的展示了瘦身的原因(摘自微信資源混淆官方文檔):
總結(jié)甲馋,安裝包大小減少的原因以下四個(gè):
相對(duì)的埂奈,可得到影響效果的因素有以下幾個(gè):
可以說(shuō),直到現(xiàn)在定躏,我們對(duì)于資源的壓縮猜到了一個(gè)極致账磺,下面是一些針對(duì)于某些資源的壓縮辦法。
其他資源
- 如果raw文件夾下有音頻文件共屈,盡量不要使用無(wú)損的音頻格式,比如wav党窜∞忠可以考慮相比于mp3同等質(zhì)量但文件更小的opus音頻格式。
- 能不用圖片的就不用圖片幌衣,除了通過(guò)前面提過(guò)的使用9Patch圖矾削、iconfont實(shí)現(xiàn)外,還可以使用shape代碼實(shí)現(xiàn)豁护,也可以考慮引進(jìn)VectorDrawable(矢量圖) 哼凯,從5.0(API等級(jí)21)開始,android開始支持矢量圖楚里。目前矢量圖兼容到API7断部,矢量圖動(dòng)畫兼容到API11。這里就不詳細(xì)講解了班缎。
終于講完了res部分蝴光,碼字好累,接下來(lái)就相對(duì)輕松了达址,首先我們要講解的是classes.dex文件蔑祟。
classes.dex
首先,什么是classes.dex沉唠?classes.dex文件是Android系統(tǒng)的可執(zhí)行文件疆虚,包含應(yīng)用程序的全部操作指令以及運(yùn)行時(shí)數(shù)據(jù)。
這里稍微介紹一下classes.dex文件的生成過(guò)程及對(duì)應(yīng)的命令:
java源代碼 -> class字節(jié)碼:[javac -source 1.6 -target 1.6 com/package1/*.java com/package2/*.java]
class字節(jié)碼 -> jar包:[jar cvf abc.jar com/package1/*.class com/package2/*.class]
jar包 -> dex文件:[dx --dex --output ***/abc.jar ***/abc_dex.jar],***是abc.jar的絕對(duì)路徑径簿。
從jar包到dex文件的過(guò)程是通過(guò)dx工具完成的罢屈,它的目的是使各個(gè)類能夠共享數(shù)據(jù),在一定程度上降低了冗余牍帚,同時(shí)也使文件結(jié)構(gòu)更加緊湊儡遮,實(shí)驗(yàn)表明,dex文件是傳統(tǒng)jar文件大小的50%左右暗赶,具體表現(xiàn)形式可以看下圖:
既然dx工具已經(jīng)辦幫我們壓縮了那么多鄙币,那我們還有什么好壓縮的呢?
當(dāng)然有蹂随,因?yàn)閐x工具并沒(méi)有壓縮class的內(nèi)容十嘿,所以我們的源代碼并沒(méi)有得到壓縮,下面我先介紹兩種常見的辦法來(lái)解決這個(gè)問(wèn)題:
和之前最簡(jiǎn)單的資源壓縮方式一樣岳锁,我們也可以在主模塊的gradle文件中配置
minifyEnabled
實(shí)現(xiàn)代碼混淆绩衷,從而減小java文件的大小。因?yàn)榛煜蟮拇a將較長(zhǎng)的文件名激率、實(shí)例咳燕、變量、方法名等等做了簡(jiǎn)化乒躺,從而實(shí)現(xiàn)字節(jié)長(zhǎng)度上的優(yōu)化招盲。我們也可以使用之前所說(shuō)的AndroidStudio提供的Lint工具執(zhí)行靜態(tài)代碼檢查,進(jìn)而刪除無(wú)用的類嘉冒、方法曹货、變量等。
上面的兩種方式雖然能夠幫助我們減少APK的大小讳推,但是實(shí)際上我們還可以做的更多顶籽。因?yàn)樯厦鎯煞N方式是自動(dòng)化的,所以必然不像人那么智能银觅。
有時(shí)候我們可能遇到這樣的情況:我們引用了一個(gè)第三方類庫(kù)礼饱,但是只用到了其中的幾個(gè)功能,其他的大部分功能一直不用究驴,這不是白白的浪費(fèi)了用戶的流量慨仿,降低了APK的下載轉(zhuǎn)化率么?為了解決這樣的問(wèn)題纳胧,我們必須借助一些工具去找到這樣的類庫(kù)镰吆,比如在文章開頭介紹過(guò)的工具:NimbleDroid,下面是我司APK目前存在的某個(gè)這樣的第三方類庫(kù):
該類庫(kù)在我司APK中只用到了掃一掃和生成二維碼這兩個(gè)功能跑慕,然而這個(gè)類庫(kù)定義的方法數(shù)竟然有1428
万皿,顯然不合理摧找,完全可以抽離其內(nèi)部的掃一掃和生成二維碼代碼,單獨(dú)實(shí)現(xiàn)牢硅。
ReDex
最后介紹一下Facebook開源的一個(gè)減少APK大小以提高性能的工具 -- ReDex蹬耘,它通過(guò)內(nèi)嵌以及清除僵尸代碼這樣的優(yōu)化方式來(lái)減少字節(jié)碼,其主要是對(duì)DEX做了優(yōu)化减余,能夠讓APK運(yùn)行更快综苔,不過(guò)需要多測(cè)試是否會(huì)崩潰。
下面分別是ReDex的教程地址和GitHub地址:
facebook/redex: A bytecode optimizer for Android apps
我個(gè)人由于時(shí)間問(wèn)題位岔,目前還未接入該工具如筛,下面就展示一下網(wǎng)友u012124438的測(cè)試數(shù)據(jù)好了:
后來(lái)我在使用 Redex 壓縮和優(yōu)化 Android APK一文的幫助下,成功的安裝并使用了ReDex抒抬,但是發(fā)現(xiàn)了以下兩個(gè)問(wèn)題:
- 用ReDex處理過(guò)的APK杨刨,其內(nèi)部的META-INF目錄會(huì)被刪除,雖然可以將ReDex處理過(guò)的APK用AndResGuard處理一下擦剑,會(huì)重新出現(xiàn)該目錄妖胀。
- 用ReDex處理過(guò)的APK,安裝好之后會(huì)出現(xiàn)Crash的問(wèn)題惠勒,目前我司測(cè)試版APK要Crash三次之后才能正常使用赚抡,而且它對(duì)于我司APK的貢獻(xiàn)只有20~25K,所以并未打算接入纠屋。
resources.arsc
最后就是對(duì)于resources.arsc文件的壓縮處理了涂臣,其實(shí)這里我們也不需要做什么,首先因?yàn)樵撐募涗浀氖琴Y源文件和資源ID的映射關(guān)系巾遭,并沒(méi)有什么值得壓縮的地方窖贤;另外如果真的有值得壓縮的地方尺栖,也只有資源文件的名字了怎抛,不過(guò)這個(gè)早就在之前因?yàn)槲覀兪褂昧宋⑿刨Y源混淆解決了拓瞪,所以此處就不再多講了呀袱。
至此稚照,針對(duì)于APK目錄結(jié)構(gòu)鲫忍,逐條分析如何為APK瘦身已經(jīng)講完了冀墨,接下來(lái)介紹一下其他的壓縮方式刚夺。
其他方式
使用APK Splits構(gòu)建APK
雖然我們上面很好的使用了resource shrinker可以回收一些未使用的資源(v7献丑、v4、google Service 等Libarry資源)侠姑,但有些資源仍然未被清除创橄。
例如:那些未使用的多套替代資源,或者是library內(nèi)部隱患著引用著的資源而我們卻沒(méi)有使用到莽红⊥孜罚或者是我們要根據(jù)用戶的手機(jī)去提供不同版本的APK邦邦,如分辨率(xxhdpi,mhdpi等),so庫(kù)等醉蚁。那么我們可以使用APK Splits大大的減少一些無(wú)用的資源燃辖,這里我們主要參考了http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits文檔。
使用多版本的APK
Multiple APK Support是一個(gè)在Google Play网棍,可以發(fā)布不同的應(yīng)用程序黔龟,分別針對(duì)不同的設(shè)備配置特征。每個(gè)APK是一個(gè)完整的滥玷、獨(dú)立的應(yīng)用程序版本氏身,但他們分享在Google Play相同的應(yīng)用程序清單,必須共享相同的包名和與簽名罗捎。Google Play 會(huì)自動(dòng)給你匹配相應(yīng)的APK观谦,這樣我們的APK 就可以是分不同版本構(gòu)建需要資源文件,從而減小APK的大小桨菜。
資源動(dòng)態(tài)加載
我們可以在項(xiàng)目中使用資源動(dòng)態(tài)加載形式豁状,例如:表情,語(yǔ)言倒得,離線庫(kù)等資源動(dòng)態(tài)加載泻红,減小APK的大小。
支持插件化
未來(lái)對(duì)于一些獨(dú)立業(yè)務(wù)模塊霞掺,可以做成插件化動(dòng)態(tài)加載谊路,用戶需要使用時(shí),只需下載少部分插件菩彬。
使用shape背景
特別是在扁平化盛行的當(dāng)下缠劝,很多純色的漸變的圓角的圖片都可以用shape實(shí)現(xiàn),代碼靈活可控骗灶,省去了大量的背景圖片惨恭。
使用著色方案
相信你的工程里也有很多selector文件,也有很多相似的圖片只是顏色不同耙旦,通過(guò)著色方案我們能大大減輕這樣的工作量脱羡,減少這樣的文件。
借助于android support庫(kù)可實(shí)現(xiàn)一個(gè)全版本兼容的著色方案免都,參考代碼:DrawableLess.java
其他方式...
總結(jié)
如果你不是一個(gè)Android開發(fā)人員锉罐,對(duì)于之前的闡述可能非常模糊,并不能明顯的表現(xiàn)出APK瘦身這件事情的意義绕娘,下面我就來(lái)總結(jié)一下:
首先脓规,針對(duì)于我司測(cè)試版APK做了哪些應(yīng)用?
字體文件使用Glyphs進(jìn)行壓縮险领,圖片使用tinypng進(jìn)行壓縮
只是用一套so文件
只使用一套圖
使用WebP圖片或SVG圖片替換某些PNG或JPG圖片
使用Google提供的Gradle插件實(shí)現(xiàn)代碼混淆和資源混淆
借助NimbleDroid侨舆、AS Anylze/Lint工具分析查找刪除不需要的代碼或資源
使用微信提供的資源混淆工具(處于穩(wěn)定性測(cè)試階段)
使用Facebook提供的ReDex工具(處于調(diào)研階段)
其次升酣,APK瘦身的效果如何?
這里我們就直接看圖好了:
可以明顯的發(fā)現(xiàn)态罪,我司的APK越來(lái)越小了噩茄,所以說(shuō),這個(gè)工作是很有意義的复颈。
最后绩聘,做一下競(jìng)品分析?
根據(jù)上面圖表耗啦,可以發(fā)現(xiàn)我們的APK的大小是十分有優(yōu)勢(shì)的凿菩,能夠很好的提高下載轉(zhuǎn)化率。而iOS那邊顯然就比較大了帜讲,雖然兩者之間不能比較衅谷,但是還是可以進(jìn)行一系列優(yōu)化的。
忠告
最后的最后似将,我想對(duì)大家說(shuō):在APK瘦身的道路上获黔,一定要掌握好度
,安排好事情的優(yōu)先級(jí)在验,如果目前要做的事情玷氏、要優(yōu)化的方面比較復(fù)雜,不僅需要花費(fèi)很長(zhǎng)的時(shí)間腋舌,而且最終效果也不明顯盏触,可以考慮之后再做,甚至不做块饺。
參考鏈接
- 【Android技術(shù)專題】APK瘦身看這一篇文章就夠了
- 那些你不知道的 APK 瘦身赞辩,讓你的 APK 更小
- Android 性能優(yōu)化系列 之 apk 瘦身
- APK文件結(jié)構(gòu)和安裝過(guò)程
- Android開發(fā)之資源目錄assets與res/raw的區(qū)別分析
- Android開發(fā)之a(chǎn)ssets目錄下資源使用總結(jié)
- Android開發(fā):最全面、最易懂的Android屏幕適配解決方案
- 是時(shí)候使用 webp 給 apk 瘦身了授艰!
- Dex文件格式詳解
- Android應(yīng)用瘦身辨嗽,從18MB到12.5MB