Android包體積優(yōu)化

背景:

?1.為什么要做包體積優(yōu)化

在2018年的Google I/O蝌焚,Google透露了Google Play上安裝包體積與下載轉化率的關系圖。


下載轉化率:一個 100MB 的應用究珊,用戶即使點了下載,也可能因為網(wǎng)絡速度慢纵苛、突然反悔下載失敗剿涮。對于一個 10MB 的應用言津,用戶點了下載之后,在猶豫要不要下的時候已經(jīng)下載完了取试。但是正如上圖的數(shù)據(jù)悬槽,安裝包大小與轉化率的關系是非常微妙的。(10MB 跟 15MB 可能差距不大瞬浓,但是 10MB 跟 40MB 的差距還是非常明顯的)

推廣成本:一般來說初婆,包體積對渠道推廣和廠商預裝的單價會有非常大的影響。特別是廠商預裝猿棉,這主要是因為廠商留給預裝應用的總空間是有限的磅叛。如果你的包體積非常大,那就會影響廠商預裝其他應用萨赁。還有一些街邊推廣需要靠數(shù)據(jù)流量來下載的場景弊琴,更是直接影響用戶的下載意向。

2. 包體積與應用性能的關系

安裝時長:文件拷貝杖爽、Library 解壓敲董、編譯 ODEX、簽名校驗等掂林,甚至包括一些混編的工程來說臣缀,初步解壓轉化就要占據(jù)很長的時間

運行內存RAM資源越多,加載到內存里的東西越多泻帮,占據(jù)內存越多,就容易越卡頓

物理內存ROM對于一些32G计寇,64G用戶來說锣杂,可能裝不了幾個大型的app

二、我們大致能做些什么番宁?

簡單來說可以分為三部分:

1:業(yè)務梳理優(yōu)化元莫,隨著時間的堆積,尤其一些大型應用蝶押,業(yè)務線不斷增多踱蠢,功能不斷增多,代碼量就上去了棋电,所以要定期清理一些舊的功能茎截,不用的,效益不好的赶盔,等等企锌,各個維度來降低業(yè)務堆積。

2: 轉變開發(fā)模式于未,配合一些混編模式撕攒,h5陡鹃,小程序分擔一些不必要的需求等方式,來減少原生代碼堆積抖坪。

3:? 技術方式瘦身萍鲸,結合實際情況,打包特性等操作擦俐,來做瘦身脊阴。我們重點說一下這一部分。

三捌肴、瘦身之前先認識apk

?1蹬叭、apk是由哪幾項組成的


?大致是由

dex代碼相關

resassets:資源相關

libso相關

meta-inf應用的簽名校驗信息相關

?2状知、分析apk的幾種方式

大致有幾種方式:

apk說到底是一個壓縮包秽五,如果實在不想使用任何工具,可以把后綴改為.zip饥悴,然后直接解壓

一個比較官方的方式apktoolapktool

使用AS坦喘,在菜單欄Build>Analyze apk ,比較清晰的看到結構和每個文件的大小

nibledroid 這個是一個比較完善的工具西设,(我沒有實踐瓣铣,感興趣的小伙伴可以去康康)

android-classyshark 是一個二進制分析工具,可以清晰看到每個包名下代碼占比

四贷揽、開始優(yōu)化

從apk結構可以看出棠笑,dex和lib是apk大小的“大頭”

先說so的優(yōu)化方式:

?soAndroid上的動態(tài)鏈接庫,在我們Android應用開發(fā)過程中禽绪,有時候Java代碼不能滿足需求蓖救,比如一些 加解密算法或者音視頻編解碼功能,這個時候就必須要通過C或者是C++來實現(xiàn)印屁,之后生成So文件提供給Java層來調用循捺,在生成So文件的時候就需要考慮生成市面上不同手機CPU架構的文件。目前雄人,Android一共 支持7種不同類型的 CPU 架構从橘,比如常見的armeabiarmeabi-v7a础钠、arm64-v8a恰力、X86等等。理論上來說珍坊,對應架構的 CPU 它的執(zhí)行效率是最高的牺勾,但是這樣會導致 lib 目錄下會多存放了各個平臺架構的 So 文件,所以App的體積自然也就更大了阵漏。

現(xiàn)在市場支持64位驻民,32位兩種系統(tǒng)的apk包翻具,打包的時候會拆包進行打包。也是為了合理的包體積優(yōu)化考慮回还。之前是只打入64位的裆泳,64位可以兼容32位,只是效率會差點柠硕,現(xiàn)在應用市場支持分包了工禾,很不錯。

1: 常見的處理方式蝗柔,拆包闻葵,根據(jù)手機架構和位數(shù)來動態(tài)適配

2: so動態(tài)下發(fā),該方案比較徹底癣丧,對包體積優(yōu)化比較友好槽畔,但是兜底方案不好制定,會存在因為下載失敗導致的某些功能暫時不可用

dex主要優(yōu)化方式:

1: 安卓ProGuard(混淆)

提到混淆胁编,大家都想到的是打包時混淆厢钧,其實遠不止此嬉橙,混淆大概有四個作用:

1-1:壓縮(Shrink): 偵測并移除代碼中無用的類、字段市框、方法和特性 1-2:優(yōu)化(Optimize): 對字節(jié)碼進行優(yōu)化,移除無用的指令 1-3:混淆(Obfuscate): 使用a,b,c,d這樣簡短而無意義的名稱枫振,對類祥得、字段和方法進行重命名 1-4:預檢(Preverify): 在Java平臺上對處理后的代碼進行預檢



代碼混淆形式一般有三種:

1:將代碼中的各個元素蒋得,比如類乒疏、函數(shù)额衙、變量的名字改變成無意義的名字。例如將 hasValue 轉換成單 個的字母 a怕吴。這樣窍侧,反編譯閱讀的人就無法通過名字來猜測用途转绷。

2:重寫代碼中的部分邏輯,將它變成功能上等價议经,但是又難以理解的形式。比如它會改變循環(huán)的指令咧织、結構體。

3:打亂代碼的格式习绢,比如多加一些空格或刪除空格闪萄,或者將一行代碼寫成多行,將多行代碼改成一行放航。

混淆規(guī)則:

http://www.reibang.com/p/d5ee2f1f977f

ps:混淆本來就是為了節(jié)約字節(jié)碼站位和反編譯風險为迈,所以盡量不要keep *,這樣就等于無效混淆了搜锰。

優(yōu)化(dontoptimize)-dontoptimize關閉優(yōu)化

壓縮(dontshrink)- dontshrink關閉壓縮

混淆(dontobfuscate)-dontobfuscate 關閉混淆

這里多說一下:

混淆非常重要大家都已經(jīng)知道了耿战,那么細看一下gradle中的配置,其中有一句是:

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro', 'mpProguard.cfg'

x0; 大家有沒有想過proguard-rules.pro這個是自己的文件狈涮,那么getDefaultProguardFile是什么,它在哪里歌馍?它的作用是什么晕鹊?

其實該getDefaultProguardFile文件所在目錄是在android/sdk/tools/proguard/溅话,是Android sdk 為我們提供的一些Android內置的一些混淆規(guī)則,可以理解為是通用配置飞几。當你沒有額外定義混淆規(guī)則時屑墨,就按通用混淆規(guī)則進行混淆纷铣。

其次說一下mapping文件灿里,這個文件也非常重要,這個文件是混淆后的輸出文件儒拂,如果遇到崩潰情況資源找不到情況色鸳,可以由該文件找到資源和混淆后字母的對應關系:


這里有個小tips:如果一個類沒有被引用命雀,是不會參與混淆的。mapping里找不到映射關系吏砂。


像我們這種大體量的app狐血,光mapping文件就一百多M了

2:andResGuard 資源混淆

原生安卓的混淆主要是針對于代碼,而工具AndResGuard主要是針對資源

x0; 3:第三方庫

第三方庫浪默,隨著項目逐漸發(fā)展缀匕,引入的第三方庫越來越多,這時候需要排查是否有功能相同的第三方庫阔加,比如圖片的第三方庫满钟,比較流行的有glide,F(xiàn)resco等,還有處理Json的也容易重復厌蔽,所以我們需要排查第三方庫奴饮,避免引入相同功能的第三方庫择浊。其次逾条,對于一些比較大的第三方,功能比較齊全担孔,有時候我們可能就只用它的一部分功能吃警,可以進行源碼依賴酌心,二次代碼剝離,但是同時也要面對版本管理問題安券。

4:移除無用代碼侯勉,無用類,無用資源

對于刪除代碼通常有兩個問題:

1: 業(yè)務代碼越來越多

2: 代碼越多越不敢刪

其實如果可以確定無用了盛龄,也就敢刪除了芳誓,所以如何確定無用就非常重要:

1:業(yè)務層面,產品直接說匿值,確定是功能下線赂摆,關聯(lián)代碼直接刪除

2:技術手段篩選無用代碼:?

2-1: 統(tǒng)計可以打點的所有page,撈取apk里所有page绊谭,取差值汪拥,就是真正的無用頁面

2-2: Lint掃描, 宪赶,掃描無用資源搂妻, 掃描無用代碼,Lint的弊端是不完全準確邓厕,因為lint的無用資源和無用代碼是割裂開進行掃描的岛蚤,尤其針對無用代碼中引用的無用資源,一般情況下掃描不到单雾,所以需要反復掃描多次她紫。我個人很少遇到誤刪的情況,但是還是需要反復確認一下比較安全渐逃。

2-3: 有一些算法民褂,加載文件處理成String赊堪,掃描文件名是否在其他文件中引用,算法也是同樣有弊端哭廉。

3: 低pv頁面轉web遵绰,低pv,參考業(yè)務埋點數(shù)據(jù)統(tǒng)計乌企。

ps: 工具simian掃描重復代碼的成玫,感興趣的小伙伴可以看一下。

額外:對于代碼編碼方向虽画,盡量少用枚舉 荣病,不要拿google源碼中也有大量枚舉來杠个盆,每減少一個 enum 可以減少大約 1.0 1.4 KB 的大小,這個是已經(jīng)被論證了的柴梆。所以盡量少用终惑。

5: 資源文件少配置


語言包只配置英文

圖片只載入一套drawable-xxhdpi

6: 打包再次壓縮(滴滴插件)

?滴滴的出的bosster 是針對打包過程中二次資源整理雹有,重復資源去重,壓縮溜宽,整理resources.arsc文件等處理的比較徹底适揉,添了google對于無用資源處理方式(不移除用一個空白文件替代)

booster

像這個體量的app煤惩,用booster保守估計可以再壓縮5-10M左右盟庞,還是比較可觀的。

7:圖片優(yōu)化

在一些大型app中票彪,圖片資源也是重中之重不狮,所以控制好圖片資源也對包體積優(yōu)化有不可或缺的貢獻。

圖片優(yōu)化大概分幾個方向:

UI層面:盡量使用原生自帶的樣式推掸,或者盡可能統(tǒng)一UI樣式,一些圖片close登渣,back等常用圖片能統(tǒng)一使用

圖片壓縮胜茧,導入包內前用壓縮工具處理壓縮

安卓原生盡量轉webp圖片使用仇味,這里需要注意不是每個png轉webp后都會體積下降,注意下即可

一些純色icon盡量用矢量圖VectorDrawable廊遍,VectorDrawable》webp》png》jpg

8:避免產生Java access方法

java access方法是贩挣,為了提供內部類和外部類直接調用掉對方私有成員變量揽惹,又不違反java的封裝性規(guī)范,Java在編譯時期自動會生成 package 可見性的靜態(tài)方法狭握。因為我們沒有引入ASM疯溺,加上該優(yōu)化方式收益并不是很大囱嫩,所以大家了解一下就好了。

https://mp.weixin.qq.com/s/ZHisCVjO_ZrtvvEWBYUQFQ

9:插件化

插件化開發(fā)能有效的大幅度降低包體積今妄,一些獨立的模塊變?yōu)椴寮_發(fā)鸳碧,從服務器拉取下來家加載,能有效的降低包體積腾仅。

build目錄下推励,這里每個目錄可以結合上一篇gradle里面task來看,這里就是每個task后輸出的對應目錄對應的內容稿黄,最后根據(jù)這些內容進行打包跌造。


參考文檔:

https://time.geekbang.org/column/article/81483

http://t.zoukankan.com/sihaixuan-p-10978222.html


此篇文章由于脫敏問題鼻听,缺失配圖联四。看個大概吧醉拓。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末亿卤,一起剝皮案震驚了整個濱河市鹿霸,隨后出現(xiàn)的幾起案子懦鼠,更是在濱河造成了極大的恐慌,老刑警劉巖街氢,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊肃,死亡現(xiàn)場離奇詭異馅笙,居然都是意外死亡延蟹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進店門斥杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蔗喂,“玉大人,你說我怎么就攤上這事畦粮」哉螅” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長钩蚊。 經(jīng)常有香客問我蹈矮,道長,這世上最難降的妖魔是什么蝠咆? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任勺美,我火速辦了婚禮碑韵,結果婚禮上祝闻,老公的妹妹穿的比我還像新娘。我一直安慰自己华蜒,他們只是感情好豁遭,可當我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布蓖谢。 她就那樣靜靜地躺著,像睡著了一般啥辨。 火紅的嫁衣襯著肌膚如雪溉知。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天,我揣著相機與錄音玫荣,去河邊找鬼崇决。 笑死底挫,一個胖子當著我的面吹牛,可吹牛的內容都是我干的盈厘。 我是一名探鬼主播官边,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼注簿,長吁一口氣:“原來是場噩夢啊……” “哼诡渴!你這毒婦竟也來了?” 一聲冷哼從身側響起惑灵,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤英支,失蹤者是張志新(化名)和其女友劉穎哮伟,沒想到半個月后妄帘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體寄摆,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年修赞,在試婚紗的時候發(fā)現(xiàn)自己被綠了婶恼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡柏副,死狀恐怖勾邦,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情割择,我是刑警寧澤珍促,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布当船,位于F島的核電站,受9級特大地震影響歉嗓,放射性物質發(fā)生泄漏。R本人自食惡果不足惜昙读,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一崖技、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧支子,春花似錦创肥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至昨登,卻和暖如春趾代,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丰辣。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工稽坤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糯俗。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓尿褪,卻偏偏與公主長得像,于是被迫代替她去往敵國和親得湘。 傳聞我的和親對象是個殘疾皇子杖玲,可洞房花燭夜當晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內容