APK瘦身屬性——android:extractNativeLibs


先描述一下結論:

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

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

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

一、起因

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

使用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;

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

打包為aar

打包為apk

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

二、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.

翻譯后:

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庫進行壓縮

三、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.1、android:extractNativeLibs = true

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

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

3.2、android:extractNativeLibs = false

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

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

3.3、結論

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

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

四、android:extractNativeLibs默認值

android:extractNativeLibs官方API描述如下:

android:extractNativeLibs官方API描述

從android:extractNativeLibs官方API描述中可以了解到:

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

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

4.1、源碼中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.2、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.3、結論

開發人員在進行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

五、參考

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 ==========

歡迎關注我的公眾號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM