1. 程式人生 > >android apk瘦身實戰

android apk瘦身實戰

瘦身的目的

app運營中經常會聽到一句話:提高下載轉化率。什麼是下載轉化率?舉個栗子:你的應用大小是 18MB ,有100個潛在使用者想要去下載嘗試使用,結果有20個使用者嫌棄安裝包太大直接揚長而去,有20個使用者在等待下載的過程中取消下載,最終只有60個使用者真正下載安裝,那麼應用的下載轉化率就是 60/100 = 60% 。
簡單的小結便是:安裝包越小,使用者下載等待的時間越短,對手機儲存配置小的裝置體驗愈佳,應用的下載轉化率也就越高。記得以前在騰訊大講堂聽微信大牛說過,微信第一個版本只有差不多 400KB ,瞬間膜拜。

安裝包的組成

要對安裝包做瘦身,首先需要了解安裝包的組成結構,
在 Android Studio 2.2.3 開始,就加入了瀏覽 APK 結構的功能,我們直接把安裝包拖入 IDE ,就可以直接瀏覽其組成和對應大小,這樣能夠很方便的對比分析出每一步優化後的結果:

這裡寫圖片描述

我們可以清楚的看到apk的各個檔案及檔案的大小,其中,

  • res檔案: 存放所有的資原始檔;
  • dex檔案: 我們編寫的java檔案會被dx工具轉換成dex檔案,執行在davilk虛擬機器上;
  • assets檔案: 存放需要保持原始檔案的資源,打包時不會被壓縮、二次處理;
  • libs: 用於存放native庫檔案,各種so;
  • resources.arsc:存放所有資源的id對映;
  • AndroidManifest: android全域性配置檔案;
  • META-INF: 存放簽名校驗相關檔案,用於保證apk的完整性和安全性;
  • 其他:其他一些配置生成的檔案;

資源瘦身
瞭解完 APK 的組成,我們可以開始著手優化的工作了,因為資原始檔在 APK 中的佔比最高,所以優先從資源瘦身開始著手。

儘量只儲存一份圖片資源

目前市面上絕大部分機型都處於 xxhdpi 的適配範圍,所以可以考慮只保留 xxhdpi 目錄下一份圖片資源,具體保留哪個目錄下的資源和保留幾份資源還得依照應用自身的實際機型分佈決定。

使用 Drawable XML、Color、.9 PNG 代替 PNG

  • 一些情況下,我們可以考慮使用 Drawable XML 來代替 PNG,如:漸變的背景圖,用幾行 XML 就可以描繪出來,何必使用幾十到上百K的 PNG 檔案;
  • 用 Color 代替 PNG,如:純色的背景;
  • 從效能上看,比起使用圖片資源需要先將其生成 Bitmap 再傳到底層交由 GPU 渲染,用 Drawable XML 和 Color 則更加高效,它是直接將 Shape 資訊傳到底層由 GPU 進行渲染,CPU 和 記憶體的佔用會更少;
  • 用 .9 PNG 代替 PNG,場景很多,不舉例了;

使用 JPG 代替 PNG

用 JPG 代替 PNG,由於 JPG 沒有 Alpha 通道,所以檔案更小,適用於不需要透明度的圖片可以考慮。

使用webp圖片格式

具體可以看下webp探尋之路,裡面有對webp的詳細介紹,這裡簡單說下webp其實是谷歌開發的一種新的圖片格式,它跟PNG有點相似,最大優點在於壓縮率高,支援有損和無失真壓縮,但是Android4.0及以上才支援webp格式,4.0以下想使用webp就需要其他輔助支援庫了。
推薦一個線上轉webp格式的網址,能立刻看到壓縮後的影象和壓縮前的影象的差別,還能按照需要選擇壓縮質量。

有損編碼格式的音訊檔案代替無損格式的音訊檔案

可以看到 Android 平臺支援的音視訊格式,下面列出有損和無損常用的格式(不要認為有損編碼就是音質很差):

無損格式:WAV,PCM,ALS,ALAC,TAK,FLAC,APE,WavPack(WV)
有損格式:MP3,AAC,WMA,Ogg Vorbis
實際開發中需要使用音訊檔案儘量採用 MP3、Ogg 這種有損格式,儘量不要用 WAV、PCM 這種無損音訊。

移除無用的資源

這裡的移除無用資原始檔主要分為兩個部分:不打包沒有使用的資源和刪除沒有使用的資源。

  • 不打包沒有使用的資源,在專案的 build.gradle 中配置 shrinkResources true 即可。
    這裡寫圖片描述

  • 刪除沒有使用的資源,通過 Android Studio 選中專案右鍵 => Analyze => inspect Code 可以檢視專案中沒有使用到的資源
    這裡寫圖片描述

即可看到所有未使用的資原始檔,建議定期清理掉這些沒用的檔案,一方面可以減小工程的大小,另一方面太多的資原始檔會導致打包後 resources.arsc 檔案變得越來越大,公司有一專案 resources.arsc 檔案已經達到 2-3 MB 的程度,有點驚人。

綜合以上幾點,就可以有效的精簡我們安裝包中的res資料夾、assets資料夾、resource.arsc檔案大小,從而達到瘦身目的。

工具

上一章節提到的是優化的思路,本章節整理在優化過程中使用到的工具。

TinyPNG:https://tinypng.com/ ,支援對 PNG/JPEG 檔案做壓縮處理,效果不錯。
pngquant:https://pngquant.org/ , 支援 PNG 壓縮,有時候 TinyPNG 處理過的圖片噪點會稍多,可以考慮用 pngquant 來處理。
ImageOptim:https://imageoptim.com/mac ,支援壓縮 PNG/JPEG/GIF ,而且效果顯著,可以看看這裡 https://www.diycode.cc/topics/496 ,遺憾的是它只支援 Mac ,Windows 黨很難過。
mozjpeg:https://imageoptim.com/mozjpeg , 用於 PNG 轉 JPEG、JPEG 壓縮,效果很好。
Adobe Audition CC:http://www.adobe.com/cn/products/audition.html ,Adobe 出品,支援對音訊的取樣率,解析度和聲道數目做更改,以此達到裁剪音訊的目的(取樣率,解析度和聲道數目是音訊檔案格式的關鍵引數,決定著音訊檔案的大小)。
以上是我優化過程中用到的覺得不錯的工具,有更好的推薦,歡迎補充。

另外,在對圖片做壓縮的時候,不要貪圖方便直接將整個資源目錄下的圖片一次性壓縮一趟。很多時候,前面做這個專案的人可能已經對一些資原始檔做過壓縮處理,很容易導致二次壓縮而引起一些圖片失真。這裡我建議是,去到應用的資源目錄下將資原始檔從大到小排序,定一個標準,如超過 20KB 的圖片要做壓縮處理,則將這些符合條件的圖片 Copy 一份出來做壓縮處理,處理後確保沒出現失真的情況下再替換對應優化前的圖片資源。 音訊檔案的處理,同理。

Native庫瘦身

Native 庫瘦身主要是減小對 CPU 架構的支援,配置起來很簡單,在 build.gradle 使用 abiFilters 配置需要用到的 CPU 架構,並將不需要相容的 so 檔案從專案中移除即可。
這裡寫圖片描述

刪除armable-v7包下的so

基本上armable的so也是相容armable-v7的,armable-v7a的庫會對圖形渲染方面有很大的改進,如果沒有這方面的要求,可以精簡。
這裡不排除有極少數裝置會Crash,可能和不同的so有一定的關係,請大家務必測試周全後再發布。

刪除x86包下的so
x86包下的so在x86型號的手機是需要的,如果產品沒用這方面的要求也可以精簡。
建議實際工作的配置是隻保留armable、armable-x86下的so檔案,算是一個折中的方案。

根據我們使用者的機型分佈,最終只保留了對 armeabi-v7a 支援。注意,這裡需要根據自家產品的實際情況來決定。

程式碼瘦身

這裡可以做的事情也是很多,主要如下:

移除廢棄功能的程式碼,反正有 VCS ,刪了程式碼隨時可以找回;
移除重複的程式碼,如:已經有了的功能程式碼,團隊成員不知道自己又寫了一套,只能靠程式碼 Review 解決了;
移除功能重疊的框架,如:專案中有幾套網路訪問框架 Volley、AsyncHttpClient、Retrofit 等,同樣只能靠程式碼 Review 解決;
移除無用的 dependencies 或者 jar 包;
減小對 Support 相容包的依賴,Support-V4 包非常大,專案引入無疑會增大 dex 檔案的大小,Google 已經意識到這個問題,所以 Support-V7 一開始就做了拆分,並且開始對 Support-V4 做拆分,雖然目前成果還不明顯,不過還是蠻值得期待的,特別是發現你少了 Support-V4 包後,可能就從2個 dex 變成1個 dex 了呢;
外掛化,一種懶載入思想的體現,先讓使用者能夠安裝宿主包,對於一些功能模組做外掛化,在特定的時機再下載安裝;
綜上所述,就可以有效的精簡我們安裝包中的 dex 檔案大小,從而達到瘦身目的。