Android apk包體優(yōu)化

1.概述

在 2018 年的 Google I/O,Google 透露Google Play 上安裝包體積與下載轉(zhuǎn)化率的關(guān)系如下圖:
gp轉(zhuǎn)化率.png

從圖中我們可以看出來隨著apk的體積增大醉箕,轉(zhuǎn)化率逐漸下降羽德。而包體對應(yīng)用的影響主要有以下幾點(diǎn):

  • 下載轉(zhuǎn)化率:一個(gè)近100M的應(yīng)用用戶在點(diǎn)擊下載之后,因?yàn)榫W(wǎng)速過慢神郊,用戶會在猶豫的過程中取消下載肴裙,而一個(gè)10M的應(yīng)用在用戶猶豫的過程中卻已經(jīng)下完了。
  • 推廣成本:
    1. 應(yīng)用的預(yù)裝對單個(gè)apk的體積有限制涌乳,apk的體積會影響到應(yīng)用的單價(jià)蜻懦。
    2. 一些移動(dòng)開發(fā)者會把a(bǔ)pk置于官網(wǎng)下載,體積過大不僅使得用戶浪費(fèi)流量夕晓,也使得開發(fā)者服務(wù)器流量浪費(fèi)宛乃。
  • 應(yīng)用市場:
    蘋果已經(jīng)限制當(dāng)應(yīng)用體積大于150M的時(shí)候只能WIFI下載,而谷歌市場要求當(dāng)應(yīng)用apk大于100M的時(shí)候使用 apk擴(kuò)展文件上傳(可參照之前的文章了解)运授,此也為應(yīng)用商店對帶寬壓力的一方面考慮烤惊。

在現(xiàn)如今眾多的超級app隨著業(yè)務(wù)的不但增加,需求的不但演進(jìn)apk體積在不斷增加吁朦,apk體積優(yōu)化閑得尤為重要柒室。google play上有一款應(yīng)用via瀏覽器,因?yàn)槠鋺?yīng)用體積小逗宜,功能相對齊全雄右。優(yōu)勢明顯比其他同類品牌的產(chǎn)品強(qiáng)出不是零星半點(diǎn)空骚。

2. apk打包流程

既然是優(yōu)化apk體積,追本溯源擂仍,當(dāng)然是從apk產(chǎn)生的過程來分析囤屹,在網(wǎng)上我們可以查到apk的組成主要由資源,代碼和第三方庫逢渔,如 so 庫等部分組成肋坚。開發(fā)過中主要是通過ant、gradle等方式編譯生成安裝包肃廓,具體流程如下:
apk打包流程.png

有此圖我們大致可以看出apk體積的優(yōu)化我們可以從resources氯葬,dex和其他資源庫三個(gè)方向去優(yōu)化容诬。將apk解壓或者通過Android Studio等工具來解壓市俊,主要關(guān)注以下幾個(gè)方面:

  1. dex個(gè)數(shù)和每個(gè)dex方法數(shù)的情況
  2. 沒有alpha通道的png圖惊窖,可壓縮成jpg減少體積;
  3. 超過一定數(shù)值的大文件哀蘑,特別是圖片資源可采用有損壓縮诚卸;
  4. 新增文件、減少文件绘迁,文件大小發(fā)生變化的情況合溺;
    下面我們從上述流程中提到的幾個(gè)方面去分析apk瘦身的方法。

3. Resources優(yōu)化

Android資源管理框架實(shí)際是由AssetManager和Resources兩個(gè)類來實(shí)現(xiàn)的脊髓。其中辫愉,Resources類可以根據(jù)ID來查找資源,而AssetManager類根據(jù)文件名來查找資源将硝。事實(shí)上恭朗,如果一個(gè)資源ID對應(yīng)的是一個(gè)文件,那么Resources類是先根據(jù)ID來找到資源文件名稱依疼,然后再將該文件名稱交給AssetManager類來打開對應(yīng)的文件的痰腮。而Resources是通過resources.arsc把Resource的ID轉(zhuǎn)化成資源文件的名稱,然后交由AssetManager來加載的律罢。關(guān)于resources.arsc的格式可以在Android源碼“/frameworks/base/include/androidfw/ResourceType.h”下查看膀值。

  1. 刪除無用資源:
    在不停的迭代中,或多或少會出現(xiàn)無用的資源误辑,包括但不限于xml沧踏、png、id巾钉、string翘狱。查找無用資源主要使用lint的UnusedResources以及UnusedIds兩個(gè)檢查規(guī)則,但是針對多l(xiāng)ibrary結(jié)構(gòu)砰苍,官方的lint在某些方面不符合我們的要求潦匈,所以我們修改了一些地方阱高。對于使用gradle的編譯的項(xiàng)目我們可以使用以下方式打包:
android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
  1. 圖片處理
  • 對于體積特別大(超過50k)的圖片資源可以考慮有損壓縮,jpg采用優(yōu)圖壓縮茬缩,png嘗試采用pngquant壓縮赤惊,輸出視覺判斷是否可行;
  • 對assets中的圖片資源也使用aapt的crunch做圖片預(yù)處理凰锡;
  • crunch有可能會使圖片變大未舟,在這種情況,我們可以替換成原圖掂为。需要注意的是對于.9.png处面,由于crunch過程中去除了黑邊,所以不能替換菩掏;
  • 對于沒有透明區(qū)域的png圖片,可以轉(zhuǎn)成jpg格式昵济。
  • 采用如webp智绸,svg等格式文件。
    關(guān)于圖片壓縮可以采用一些第三方的網(wǎng)站壓縮如熊貓推薦一個(gè)自己寫的腳本ImageProcess通過該網(wǎng)站批量壓縮圖片访忿。
  1. 字符編碼
    resources.arsc中的會有一個(gè)去重過的字符串資源池(相同的兩個(gè)字符串其實(shí)用的是同一份)瞧栗,每個(gè)String使用偏移值來獲取資源池中的數(shù)值。ResourceTable的編碼對于resources.arsc的體積有很大影響海铆。這樣的好處就是處理純英文等直接通過ascii存儲語言的國家資源文件將會更小迹恐,而對于中文、日文這些國家的資源文件有可能會變大卧斟。
  2. 指定文件的壓縮方式與7zip壓縮
    安裝包是一個(gè)壓縮文件殴边,我們可以指定里面的文件采用哪種壓縮方式,比如一些文件我們可以采用一些極致壓縮到最小珍语,然后安裝成功后再解壓锤岸,或者安裝完成后從服務(wù)器下載再解壓,但此舉會對啟動(dòng)速度有一定的影響板乙。
  3. 語言包動(dòng)態(tài)加載
  4. 資源混淆是偷,我們常常用proguard來混淆代碼,同樣資源也是可以混淆的募逞,會生成a,b,c命名的png 和xml蛋铆,讓反編譯更加難受,不過這其中需要注意資源映射問題放接。
  5. 產(chǎn)品做減法刺啦。

4. Dex 優(yōu)化

對于大部分應(yīng)用來說Dex的個(gè)數(shù)和Dex的體積是整個(gè)應(yīng)用的大部頭,因此Dex的優(yōu)化在對包體優(yōu)化起到了關(guān)鍵作用透乾,主要有以下幾個(gè)部分:

  1. ProGuard 混淆
    你可以通過下面的方法輸出 ProGuard 的最終配置洪燥,需要注意各種的 keep *磕秤,很多情況下我們只需要 keep某個(gè)包名,方法名捧韵,類名即可市咆。
-printconfiguration  configuration.txt

但我們可以加大力度混淆,比如對非export的四大組件和View進(jìn)行混淆再来,但我們要注意以下兩個(gè)方面的問題

xml

清單文件中的xml需要同步修改

代碼替換

代碼中不可出現(xiàn)運(yùn)算拼接出來的類名

// 情況一:變量
public String activityName = "com.sample.TestActivity";
// 情況二:方法體
startActivity(new Intent(this, "com.sample.TestActivity"));
// 情況三:通過運(yùn)算得到蒙兰,不支持
startActivity(new Intent(this, "com.sample" + ".TestActivity"));

餓了么曾經(jīng)實(shí)現(xiàn)過一款混淆四大組件的庫Mess,具備一定的參考價(jià)值。
Android Studio 3.0推出了Android新Dex編譯器D8與新混淆工具R8可以在編譯過程中生成的dex大概減少3%芒篷,但此功能還在測試階段搜变。

  1. Dex 分包
    正如我們所知同一個(gè)應(yīng)用可能會存在多個(gè)Dex包,每個(gè)Dex 包的也會存在相互之間的引用针炉,因此在Dex的分包規(guī)則上我們同樣具備優(yōu)化的方法挠他,比如避免Dex包之間的冗余和Dex包生成的算法優(yōu)化。具體的我們需要先了解Dex文件的格式和生成規(guī)則篡帕,其中主要是優(yōu)化Dex的格式中debugItems模塊殖侵。

5. 其他資源優(yōu)化

一個(gè)應(yīng)用除了Java代碼,resource等資源之外镰烧,還存在一個(gè)Native library等相關(guān)資源拢军。這塊主要是針對一些Native 資源進(jìn)行優(yōu)化。

  1. 減少冗余
    例如一些so庫中C++運(yùn)行庫大多使用靜態(tài)編譯方式怔鳖,使用stlport_shared方式可減小APK包大小茉唉,相當(dāng)于把大家公有的代碼提取出來放一份,減少冗余结执。同時(shí)也會節(jié)省一點(diǎn)內(nèi)存度陆,加載so的時(shí)候動(dòng)態(tài)庫只會加載一次,靜態(tài)庫則隨著so的加載被加載多份內(nèi)存映像昌犹。主要為了減少冗余模塊坚芜。大家都用到的一些基礎(chǔ)功能,應(yīng)該抽成基礎(chǔ)模塊斜姥。
  2. so庫壓縮
    我們可以針對一些so庫進(jìn)行特殊壓縮鸿竖,需要時(shí)解壓,甚至可以從網(wǎng)絡(luò)獲取到本地進(jìn)行加載铸敏。

以上為對apk體積優(yōu)化的一些總結(jié)缚忧,當(dāng)然會還有一些其他的可以優(yōu)化的點(diǎn),歡迎大家補(bǔ)充杈笔。
針對資源壓縮主要是目前瀏覽器引用微信的AndResGuard有著明顯的效果闪水。

參考
極客時(shí)間Android開發(fā)高手課
Dex文件格式詳解
美團(tuán)Android App包瘦身優(yōu)化實(shí)踐
支付寶Android 包大小極致壓縮
微信Android安裝包相關(guān)知識匯總
FaceBook Redex

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蒙具,隨后出現(xiàn)的幾起案子球榆,更是在濱河造成了極大的恐慌朽肥,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件持钉,死亡現(xiàn)場離奇詭異衡招,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)每强,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進(jìn)店門始腾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人空执,你說我怎么就攤上這事浪箭。” “怎么了辨绊?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵奶栖,是天一觀的道長。 經(jīng)常有香客問我门坷,道長驼抹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任拜鹤,我火速辦了婚禮,結(jié)果婚禮上流椒,老公的妹妹穿的比我還像新娘敏簿。我一直安慰自己,他們只是感情好宣虾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布惯裕。 她就那樣靜靜地躺著,像睡著了一般绣硝。 火紅的嫁衣襯著肌膚如雪蜻势。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天鹉胖,我揣著相機(jī)與錄音握玛,去河邊找鬼。 笑死甫菠,一個(gè)胖子當(dāng)著我的面吹牛挠铲,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寂诱,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拂苹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了痰洒?” 一聲冷哼從身側(cè)響起瓢棒,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤浴韭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后脯宿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體念颈,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年嗅绰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了舍肠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡窘面,死狀恐怖翠语,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情财边,我是刑警寧澤肌括,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站酣难,受9級特大地震影響谍夭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜憨募,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一紧索、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧菜谣,春花似錦珠漂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至冈敛,卻和暖如春待笑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抓谴。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工暮蹂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人癌压。 一個(gè)月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓椎侠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親措拇。 傳聞我的和親對象是個(gè)殘疾皇子我纪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容