APK瘦身屬性——android:extractNativeLibs

先描述一下結論:html

android:extractNativeLibs = true時,gradle打包時會對工程中的so庫進行壓縮,最終生成apk包的體積會減少
但用戶在手機端進行apk安裝時,系統會對壓縮後的so庫進行解壓,從而形成用戶安裝apk的時間變長java

關於android:extractNativeLibs默認值設定方面,若開發人員未對android:extractNativeLibs進行特殊配置:android

  • minSdkVersion < 23 或 Android Gradle plugin < 3.6.0狀況下,打包時 android:extractNativeLibs=true
  • minSdkVersion >= 23 而且 Android Gradle plugin >= 3.6.0狀況下,打包時android:extractNativeLibs=false

1、原由

偶然發現,使用AndroidStudio將同一Module分別打包爲aarapk,二者佔用的磁盤空間差距巨大:
打包爲aar,佔用磁盤空間4.4M;打包爲apk,佔用磁盤空間爲11.7M;app

使用AndroidStudio中 apkanalyzer 對比分析,兩種打包方式so庫 Rwa File Size 差距較大,但二者的Download Size 大小徹底一致:
打包爲aar,so庫Rwa File Size爲3.4M;打包爲apk,so庫Rwa File Size爲8.2M;
打包爲aar,so庫Download Size爲3.3M;打包爲apk,so庫Download Size爲3.3M;ide

兩種打包方式 apkanalyzer 對比分析以下:gradle

打包爲aar

打包爲apk

兩種打包方式Rwa File SizeDownload Size 差距較大,那Raw File SizeDownload Size又是如何定義的呢?ui

2、Raw File Size & Download Size

官方 view_file_and_size_information: 描述以下:插件

APK Analyzer shows raw file size and download file size values for each entity, as shown in figure 1. Raw File Size represents the unzipped size of the entity on disk while Download Size represents the estimated compressed size of the entity as it would be delivered by Google Play. The % of Total Download Size indicates the percentage of the APK's total download size the entity represents.翻譯

翻譯後:code

APK Analyzer 展現每一個實體的 Raw File Sizedownload file size
Raw File Size 表明對應實體在磁盤上未進行壓縮的大小;
Download Size 表明對應實體在Google Play中,預估的壓縮後的大小;
% of Total Download Size 表明對應模塊實體,在Download Size總大小中所佔百分比。

View file and size information

看到這裏,懷疑:

打包爲aar時,AndroidStudio對Module中的so庫進行了壓縮;但打包爲apk時,未對Module中的so庫進行壓縮

3、android:extractNativeLibs

查詢相關資料,發現文章Android APK Raw File Size vs Download Size:
文章中提到:
打包APK時,是否對so庫進行壓縮的控制屬性爲 android:extractNativeLibs

Android APK Raw File Size vs Download Size

AndroidManifest.xmlextractNativeLibs屬性使用方式:

<application
    android:extractNativeLibs="true">
</application>

3.一、android:extractNativeLibs = true

android:extractNativeLibs = true,進行apk打包時,AndroidStudio會對Module中的so庫進行壓縮,最終獲得的apk體積較小。

  • 好處是:用戶在應用市場下載和升級時,由於消耗的流量較小,用戶有更強的下載和升級意願。
  • 缺點是:由於so是壓縮存儲的,所以用戶安裝時,系統會將so解壓出來,從新存儲一份。所以安裝時間會變長,佔用的用戶磁盤存儲空間反而會增大。

3.二、android:extractNativeLibs = false

android:extractNativeLibs = false,進行apk打包時,AndroidStudio不會對Module中的so庫進行壓縮,最終生成的apk體積較大。

  • 好處是:用戶安裝後,直接使用/data/data/your.app.package/lib路徑下的so,沒有額外的so複製操做,相對於android:extractNativeLibs = true而言,節省用戶磁盤存儲空間;

3.三、結論

android:extractNativeLibs = true的設定仍是利大於弊的。

設置爲true能夠工程中的so庫進行壓縮,最終減少生成的apk包大小。至於安裝應用時,因so庫解壓縮而形成的安裝時間增加,相對於帶來的好處(提升應用市場用戶的下載和升級意願)而言,我認爲是可接受的。

4、android:extractNativeLibs默認值

android:extractNativeLibs官方API描述以下:

android:extractNativeLibs官方API描述

從android:extractNativeLibs官方API描述中能夠了解到:

  • 源碼中 android:extractNativeLibs默認值爲true;
  • 編譯器Android Gradle plugin 3.6.0 或更高版本,android:extractNativeLibs默認值爲false;

但真的是這樣嗎?一塊兒來探究一下。

4.一、源碼中extractNativeLibs默認設定

從Android 6.0(API 23)開始,Android frame源碼中PackageParser.java在讀取android:extractNativeLibs屬性值時,默認值爲true;

對應的源碼路徑:frameworks/base/core/java/android/content/pm/PackageParser.java

if (sa.getBoolean(
        com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
        true)) {
    ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}

4.二、Android Gradle plugin 3.6.0 或更高版本

編譯器Android Gradle plugin 3.6.0 或更高版本,在構建應用時會默認將 extractNativeLibs 設置爲 false

經過觀察編譯後生成的AndroidManifest.xml文件,發現 gradle 插件設置默認值爲false,是經過在處理AndroidManifest.xml文件的時,在其中自動插入 android:extractNativeLibs=「false"來實現的
因爲 android:extractNativeLibs 這個屬性是在Android 6.0(API 23)引入的,所以若是項目配置 中minSdkVersion < 23 的話,gradle 插件不會自動插入android:extractNativeLibs=「false"

4.三、結論

開發人員在進行apk打包時,若未對android:extractNativeLibs進行特殊配置:

  • minSdkVersion < 23 或 Android Gradle plugin < 3.6.0,打包時 android:extractNativeLibs=true
  • minSdkVersion >= 23 而且 Android Gradle plugin >= 3.6.0,打包時android:extractNativeLibs=false

5、參考

apkanalyzer:
https://developer.android.com/studio/command-line/apkanalyzer

view_file_and_size_information:
https://developer.android.com/studio/build/apk-analyzer.html#view_file_and_size_information

Android APK Raw File Size vs Download Size:
https://stackoverflow.com/questions/45024723/android-apk-raw-file-size-vs-download-size-how-to-shrink-the-raw-file-size

android:extractNativeLibs:
https://developer.android.com/guide/topics/manifest/application-element.html#extractNativeLibs

Setting android:extractNativeLibs to reduce app size:
https://stackoverflow.com/questions/42998083/setting-androidextractnativelibs-false-to-reduce-app-size

========== THE END ==========

歡迎關注個人公衆號

相關文章
相關標籤/搜索