1. 程式人生 > >簡單好使的操作——將Android apk大小減少 60%

簡單好使的操作——將Android apk大小減少 60%

越小越好

作為一個開發者我們總是更關心應用的效能,設計和使用者體驗。但是,大多數開發者都忘了(或低估)一件事:應用體積。如果你希望你的應用能吸引大量使用者,這是非常核心的一點。

市場上大概有 11000 種安卓機型,而其中大部分都是低端機,有限的儲存(1GB 到 8GB),甚至用的還是 2G 或者 3G 網路。這些裝置在印度,巴其爾等非洲發展中國家佔有大量市場,你可以在這些地方獲得大量的使用者。

讓你的應用大小保持最佳變得尤其重要。你的應用體積越小,你的使用者就有更多的空間來儲存他們的視訊和圖片。說實話,你肯定不希望使用者因為“儲存空間不足”的提示刪除你的應用。

如果使用者的儲存空間不夠的話,他們會解除安裝你的應用。
這些發展中國家使用者使用的依然是速度有限的 2G/3G 網。所以,如果你的應用體積太大,將會需要更多的時間來下載(更可能的情況時使用者根本不會去下載)。同樣的,大多數使用者流量有限,使用者下載的每個位元組都是在花錢。

所以,很明顯了,應用程式界的真理就是:

越小越好

使用 APK Analyser 分解你的 APK

Android Studio 提供了一個有用的工具:APK Analyser。APK Analyser 將會拆解你的應用並讓你知道 .apk 檔案中的那個部分佔據了大量空間。讓我們看一下 Anti-Theft 在沒有經過優化之前的截圖。

從 Apk Analyser 的輸出來看,應用的原大小是 3.1MB。經過 Play 商店的壓縮,大致是 2.5MB。

從截圖中可以看出主要有 3 個資料夾佔據了應用的大多數空間。

  • classes.dex —— 這是 dex 檔案,包含了所有會執行在你的 DVM 或 ART 裡的位元組碼檔案。
  • res —— 這個資料夾包含了所有在 res 資料夾下的檔案。大部分情況下它包含所有圖片,圖示和原始檔,選單檔案和佈局。
  • resources.arsc —— 這個檔案包含了所有 value 資源。這個檔案包含了你 value 目錄下的所有資料。包括 strings、dimensions、styles、intergers、ids 等等。

所以,現在你知道 APK 是怎麼組成的了。讓我們接著看看該怎麼一塊塊的優化它以減小應用體積。

減小 classes.dex

classes.dex 包含了所有 Java 程式碼。當你編譯你的應用時,gradle 會將你的所有模組裡的 .class 檔案轉換成 .dex 檔案並將這些檔案合成一個 classes.dex 檔案。

單個的 classes.dex 檔案可以容納大約 64K 方法。如果你達到了這個限制,你必須要在你的工程中啟用 multidexing。這將會建立另一個 classes1.dex 檔案去儲存剩下的方法。所以 classes.dex 檔案數目由你的方法數而定。

你可以看到現在的 “Anti-Theft Screen Lock” 包含 4392 個類和 29897 個方法。這個結果是沒有經過混淆的。你有兩個預設的混淆檔案。

  • proguard-android-optimize.txt
  • proguard-android.txt

就像檔名寫的那樣,“proguard-android-optimize.txt”是更積極的混淆選項。我們將這個作為預設的混淆配置。你可以在 /app 目錄下的 proguard-rules.pro 裡新增自定義的混淆配置。

 release {
    //Enable the proguard
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"

    //Other parameters
    debuggable false
    jniDebuggable false
    renderscriptDebuggable false
    signingConfig playStoreConfig //Add your own signing config
    pseudoLocalesEnabled false
    zipAlignEnabled true
}

通過設定 minifyEnabled 為 true,混淆將會移除所有未使用的方法、指令以減小 classes.dex 檔案。

這是啟用了 minify 之後的 APK。

你可以看到在為每個模組啟用了混淆之後我們的 classes.dex 大小減小了幾乎 50%。同時你可以看到方法數從 29897 降到了 15168(幾乎 50%)。恭喜……��

體積從 3.1MB 降到了 1.98MB。(縮小約 50%)

減小 res:

下一大塊就是 res 資料夾,它包括了所有的圖片,raw 檔案和 XML。你不能新增/刪除/修改你的 XML,因為它們包含了你的佈局。但是我們可以減小圖片檔案。

  • shrinkResources” 屬性將會移除所有在工程中沒有用到的資源。在 build.gradle 中像下面這樣啟用它:
release{
  //...
  //...
  shrinkResources true
  //...
}
  • resConfigs” 屬性將會在構建過程中移除所有本地化資源。app “Anti-Theft Screen Lock” 只需要支援英語。而很多的支援庫都可能有其它語言的本地化資料夾。這些是我不需要的。所以,新增下面的這些程式碼讓應用只支援英語。
defaultConfig {
    //...
    //...
    //...

    //strip other than english resources
    resConfigs "en"
}
  • 如果你在用 Android Studio 2.3,並且你的應用的最低支援版本大於 18,你可以使用 webp 替代 png。webp 圖片比 png 體積更小但質量一樣。而且 Android 支援 webp。所以你可以在 ImageView 中像載入其它光柵圖片一樣載入 webp 圖片。這不需要改變你的佈局。

你可以在工程選擇 drawable 和 mipmap 資料夾,右擊並選擇 convert to webp。這將會開啟下面這樣的配置彈框。

點選 ok,將會將所有 png 圖片轉成 webp。如果 webp 圖片比 png 更大,Android Studio 將會自動跳過這個檔案。

讓我們看下最終效果:

喔!!!res 資料夾從 710KB 降到了 597KB。

體積減小了 105KB。(降低了 16%)

你也可以將圖片轉為向量圖。但是這樣你需要對它的向後相容性進行一些處理。如果你想了解更多 vector 的相關知識,看看 Chris Banes 的這篇部落格

TL;DR:

  • 通過在你的 release build type 中加上下面這些程式碼啟用混淆。
  • 啟用 shrinkResources。
  • 通過在 “resConfigs” 裡新增需要的資源名移除所有不需要的本地化資源。
  • 將所有圖片轉為 webp 或者向量圖。

總結:

通過使用上面這些簡單的技巧我將應用體積從 3.19MB 降至了 1.89MB。

這些只是最簡單的方式,還有很多減小應用體積的方法。但是,你應該始終使用上面這些簡單的方法來保證已經儘可能的減小了應用體積。