Android apk瘦身最佳實(shí)踐(二):代碼混淆和資源壓縮

要盡可能減小 APK 文件帽芽,我們應(yīng)該啟用壓縮來(lái)移除發(fā)布構(gòu)建中未使用的代碼和資源。

1. 使用 ProGuard 混淆代碼

在 Android 中代碼混淆和壓縮都是通過(guò) ProGuard 來(lái)實(shí)現(xiàn)的,ProGuard 會(huì)檢測(cè)和移除代碼中未使用的類(lèi)手趣、字段阁最、方法和屬性,除此外還可以?xún)?yōu)化字節(jié)碼成玫,移除未使用的代碼指令加酵,以及用短名稱(chēng)混淆類(lèi)拳喻、字段和方法。

在 build.gradle 中猪腕,使用 minifyEnabled 屬性來(lái)開(kāi)啟代碼混淆:

android {
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),
                    'proguard-rules.pro'
        }
    }
    ...
}

2. 使用 shrinkResources 壓縮資源

在 build.gradle 中使用 shrinkResources 屬性來(lái)開(kāi)啟資源壓縮冗澈,它在構(gòu)建 apk 時(shí)可以移除那些沒(méi)有引用到的資源文件,通常它必須與 minifyEnabled 屬性一起使用:

release {
    shrinkResources true
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'),
            'proguard-rules.pro'
}

需要注意的是码撰,開(kāi)啟該屬性設(shè)置后渗柿,它并不會(huì)移除 values/ 文件夾中定義的資源,例如:字符串脖岛、顏色朵栖、樣式等等。

3. 混淆壓縮對(duì)比

為了鑒定一下代碼混淆與資源壓縮到底有多大作用柴梆,我們隨便找個(gè)簡(jiǎn)單的 app 工程來(lái)實(shí)驗(yàn)一下陨溅。

minifyEnabled shrinkResources apk大小
false false 4,285,579 字節(jié),約4.3M
true false 3,781,347 字節(jié)绍在,約3.8M
true true 3,779,525 字節(jié)门扇,約3.8M
false true 無(wú)法編譯

從中我們可以得到一些結(jié)論:

  1. 開(kāi)啟代碼混淆和資源壓縮后,apk 大小減少了約0.5M偿渡,一個(gè)小工程都尚且如此臼寄,在一個(gè)比較龐大的工程中開(kāi)啟這倆選項(xiàng),壓縮的大小還是很可觀的溜宽。
  2. 開(kāi)啟資源壓縮與不開(kāi)啟相比吉拳,只減少了約2000多字節(jié)的大小,可見(jiàn)大頭還是靠代碼混淆适揉,資源壓縮只能起到錦上添花的作用留攒。
  3. 關(guān)閉代碼混淆開(kāi)啟資源壓縮,你會(huì)發(fā)現(xiàn)無(wú)法編譯嫉嘀,Android Studio 會(huì)提示你這倆必須配對(duì)使用炼邀,要開(kāi)啟資源壓縮必須得開(kāi)啟代碼混淆。

4. 資源壓縮會(huì)保留文件名不保留內(nèi)容

我們?cè)僮鰝€(gè)測(cè)試剪侮,在應(yīng)用的資源中放一張png圖片姑且命名為 test.png拭宁,放一個(gè)layout布局文件命名為test.xml,并且確保這2個(gè)資源文件沒(méi)有任何代碼會(huì)引用瓣俯,我們開(kāi)啟代碼混淆和資源壓縮打包生成apk文件杰标。

生成apk文件后,直接將apk包拖到 Android Studio 中降铸,可以查看apk包的相關(guān)信息在旱,細(xì)心一點(diǎn)的話你會(huì)發(fā)現(xiàn)幾個(gè)有趣的現(xiàn)象:

  1. 在圖片資源文件夾中,仍然可以看到名為 test.png 的圖片推掸,但是你打開(kāi)看到的是一個(gè) 1*1 的圖片桶蝎;
  2. 在 layout 文件夾中驻仅,仍然可以看到名為 test.xml 的文件,打開(kāi)看到的是一個(gè)空的xml文件登渣,沒(méi)有任何xml節(jié)點(diǎn)信息噪服;

也就是說(shuō),資源壓縮后胜茧,并不是直接刪除了沒(méi)有用到的資源文件粘优,而是生成了對(duì)應(yīng)的占位文件,這些占位文件都是空文件呻顽,相比原文件大小可以忽略不計(jì)雹顺。這樣做的原因是:每個(gè)資源文件都對(duì)應(yīng) R.class 里的一個(gè)資源 id ,資源 id 的映射關(guān)系會(huì)打包在 resources.arsc 文件里廊遍,如果直接刪除了資源文件嬉愧,則可能需要同時(shí)修改 resources.arsc 里的資源映射表,這樣是很繁瑣的過(guò)程喉前,而用占位文件來(lái)替換則避免了這種情況没酣。

5. 使用 resConfigs 去除多余的語(yǔ)言包

目前很多第三方庫(kù)內(nèi)包含了各種語(yǔ)言包,但是大多數(shù)情況下我們的應(yīng)用是不需要國(guó)際化卵迂,僅僅需要中文的就可以了裕便,所以可以 resConfigs 配置來(lái)去掉多余的語(yǔ)言包:

android {
    defaultConfig {
        ...
        resConfigs "zh"
    }
}

如上所示,打包時(shí)只會(huì)將中文的資源包打進(jìn)去见咒,這樣也可以一定程度上減小 apk 的體積偿衰。

6. ProGuard 中的壓縮優(yōu)化配置

關(guān)于 ProGuard 的配置有很多,具體需要查看文檔才能知道作用是什么论颅。剛開(kāi)始接觸的時(shí)候哎垦,我以為 ProGuard 只是做代碼混淆而用的囱嫩,其實(shí)它的作用不僅僅如此恃疯,有2個(gè)配置我們經(jīng)常會(huì)忽略掉:

  • -dontshrink
    聲明不進(jìn)行壓縮操作。
  • -dontoptimize
    不對(duì) class 進(jìn)行優(yōu)化墨闲,默認(rèn)是開(kāi)啟優(yōu)化的今妄。由于優(yōu)化會(huì)進(jìn)行類(lèi)合并、內(nèi)聯(lián)等鸳碧,使用熱修復(fù)的應(yīng)用盾鳞,建議關(guān)閉優(yōu)化。

我發(fā)現(xiàn)很多第三方庫(kù)瞻离,例如友盟統(tǒng)計(jì)SDK腾仅,官方給出的 ProGuard 配置都需要加上該配置,也就是說(shuō)不進(jìn)行代碼優(yōu)化套利、壓縮推励,往往初次接觸者不明所以的照搬了鹤耍。但其實(shí)如果你的應(yīng)用沒(méi)有采用熱更新方案之類(lèi)的,在 ProGuard 里去掉這2個(gè)配置验辞,你會(huì)發(fā)現(xiàn)這對(duì)減小 apk 的大小效果很顯著稿黄。

以我們自己的一個(gè)應(yīng)用為例,ProGuard 里加上這2個(gè)配置打出來(lái)的 apk 包大小約為 25.5M跌造,去掉這2個(gè)配置之后打出的包大小約為 24.1M杆怕。簡(jiǎn)直不敢相信,就這么2個(gè)小小的配置壳贪,居然能讓包大小縮減 1.4M 左右陵珍,效果非常明顯。

但是违施,實(shí)操過(guò)程中撑教,我們發(fā)現(xiàn)有些頁(yè)面的圖標(biāo)丟失變成黑色了,這些因?yàn)?ProGuard 判定某些資源文件沒(méi)有被使用醉拓,將它轉(zhuǎn)換成了一個(gè) 1*1 的占位文件了伟姐。這需要我們手動(dòng)在 res/raw/keep.xml 里配置,明確告訴 ProGuard 哪些資源文件是不需要混淆壓縮的亿卤,以為自己的一個(gè)配置為例:

<?xml version="1.0" encoding="utf-8"?>
<resources
    xmlns:tools="http://schemas.android.com/tools"
    tools:shrinkMode="safe"
    tools:keep="@mipmap/emoji_*,@mipmap/jietiao_ic_module_*"
    >
</resources>

7. 小結(jié)

采用 ProGuard 是減小 apk 大小非常有效的方法之一愤兵,但是使用過(guò)程中可能附帶很多問(wèn)題:有可能打包不成功、有可能圖片資源問(wèn)題丟失排吴、有可能莫明其妙的閃退秆乳,這些都需要我們對(duì) ProGuard 的配置有個(gè)基本的了解,遇到問(wèn)題才能迎刃而解钻哩,用好了它相信會(huì)有很大的幫助屹堰。

系列文章
Android apk瘦身最佳實(shí)踐(一):去除R.class
Android apk瘦身最佳實(shí)踐(二):代碼混淆和資源壓縮
Android apk瘦身最佳實(shí)踐(三):資源混淆原理
Android apk瘦身最佳實(shí)踐(四):采用AndResGuard進(jìn)行資源混淆
Android apk瘦身最佳實(shí)踐(五):圖片壓縮
Android apk瘦身最佳實(shí)踐(六):采用D8編譯器

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市街氢,隨后出現(xiàn)的幾起案子扯键,更是在濱河造成了極大的恐慌,老刑警劉巖珊肃,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荣刑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡伦乔,警方通過(guò)查閱死者的電腦和手機(jī)厉亏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烈和,“玉大人爱只,你說(shuō)我怎么就攤上這事≌猩玻” “怎么了恬试?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵沥匈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我忘渔,道長(zhǎng)高帖,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任畦粮,我火速辦了婚禮散址,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宣赔。我一直安慰自己预麸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布儒将。 她就那樣靜靜地躺著吏祸,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钩蚊。 梳的紋絲不亂的頭發(fā)上贡翘,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音砰逻,去河邊找鬼鸣驱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛蝠咆,可吹牛的內(nèi)容都是我干的踊东。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼刚操,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闸翅!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起菊霜,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坚冀,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后占卧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體遗菠,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡联喘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年华蜒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豁遭。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡叭喜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蓖谢,到底是詐尸還是另有隱情捂蕴,我是刑警寧澤譬涡,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站啥辨,受9級(jí)特大地震影響涡匀,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜溉知,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一陨瘩、第九天 我趴在偏房一處隱蔽的房頂上張望梦湘。 院中可真熱鬧艘策,春花似錦淤齐、人聲如沸淑履。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)坦袍。三九已至匕争,卻和暖如春捅厂,著一層夾襖步出監(jiān)牢的瞬間贯卦,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工焙贷, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留脸侥,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓盈厘,卻偏偏與公主長(zhǎng)得像睁枕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子沸手,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354