先描述一下結論: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
;偶然發現,使用AndroidStudio將同一Module分別打包爲aar
與apk
,二者佔用的磁盤空間差距巨大:
打包爲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
兩種打包方式Rwa File Size
與Download Size
差距較大,那Raw File Size
與Download Size
又是如何定義的呢?ui
官方 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 Size
與download file size
:
Raw File Size
表明對應實體在磁盤上未進行壓縮的大小;
Download Size
表明對應實體在Google Play中,預估的壓縮後的大小;
% of Total Download Size
表明對應模塊實體,在Download Size總大小中所佔百分比。
打包爲aar時,AndroidStudio對Module中的so庫進行了壓縮;但打包爲apk時,未對Module中的so庫進行壓縮
。
查詢相關資料,發現文章Android APK Raw File Size vs Download Size:
文章中提到:
打包APK時,是否對so庫進行壓縮
的控制屬性爲 android:extractNativeLibs
。
AndroidManifest.xml
中extractNativeLibs
屬性使用方式:
<application android:extractNativeLibs="true"> </application>
若android:extractNativeLibs = true
,進行apk打包時,AndroidStudio會對Module中的so庫進行壓縮
,最終獲得的apk體積較小。
好處是:
用戶在應用市場下載和升級時,由於消耗的流量較小,用戶有更強的下載和升級意願。缺點是:
由於so是壓縮存儲的,所以用戶安裝時,系統會將so解壓出來,從新存儲一份。所以安裝時間會變長,佔用的用戶磁盤存儲空間反而會增大。若android:extractNativeLibs = false
,進行apk打包時,AndroidStudio不會對Module中的so庫進行壓縮
,最終生成的apk體積較大。
好處是:
用戶安裝後,直接使用/data/data/your.app.package/lib
路徑下的so,沒有額外的so複製操做,相對於android:extractNativeLibs = true
而言,節省用戶磁盤存儲空間;android:extractNativeLibs = true的設定仍是利大於弊的。
設置爲true能夠工程中的so庫進行壓縮,最終減少生成的apk包大小。至於安裝應用時,因so庫解壓縮而形成的安裝時間增加,相對於帶來的好處(提升應用市場用戶的下載和升級意願)而言,我認爲是可接受的。
android:extractNativeLibs官方API描述以下:
從android:extractNativeLibs官方API描述中能夠了解到:
但真的是這樣嗎?一塊兒來探究一下。
從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; }
編譯器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"
。
開發人員在進行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