extractNativeLibs這個屬性相信安卓開發者都不會陌生,先引用官方文檔說明一下此屬性的含義
android:extractNativeLibs
軟件包安裝程序是否將原生庫從 APK 提取到文件系統。如果設爲 false,則原生庫必須保持頁面對齊狀態並以未壓縮的形式存儲在 APK 中。無需更改代碼,因爲鏈接器在運行時直接從 APK 加載庫。
默認值爲 "true"
含義比較明確,就是如果這個屬性設置爲 false
,那麼 apk
的體積會變大,但是 apk
安裝後系統會直接使用 apk
中的 so
,這樣就節約了用戶的存儲空間。反之,如果這個屬性設置爲 true
,那麼 apk
的體積會更小,因爲 so
是壓縮存儲的,但是在 apk
安裝的時候,系統會把 apk
中的 so
解壓重新存儲一份,導致佔用的存儲空間變大。
設置這個屬性的方法就是直接在 AndroidManifest.xml
中聲明即可。
<application
android:extractNativeLibs="true"
... >
</application>
如何確認apk
中so
是壓縮存儲的還是未壓縮存儲的呢,使用zipinfo
這個命令就行了
@debian-ts:~/tmp $ zipinfo test-store.apk *.so
-rw---- 2.4 fat 13776 b- stor 80-000-00 00:00 lib/armeabi-v7a/libtest.so
@debian-ts:~/tmp $ zipinfo test-deflate.apk *.so
-rw---- 2.4 fat 13776 b- defN 80-000-00 00:00 lib/armeabi-v7a/libtest.so
如果對 zip
壓縮格式有了解的話就知道,stor
爲不壓縮存儲,defN
爲壓縮存儲。
官方文檔上寫明瞭默認值爲 true
,這個沒錯,因爲查看 系統源碼 可以發現,讀取這個屬性的時候會以 true
作爲默認值
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_extractNativeLibs,
true)) {
ai.flags |= ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
}
如果在 AndroidManifest.xml
中主動設置了 android:extractNativeLibs
,那沒得說肯定設置的是什麼值就是什麼值。但是如果默認沒有設置,那就有講究了。
從 AGP (Android Gradle Plugin) 的 CHANGELOG
中,我們可以看到,在 AGP 3.6.0 版本中,google
更新了 extractNativeLibs
的默認行爲,在構建應用時,插件現在默認會將 extractNativeLibs 設置爲 false
。
通過觀察編譯後生成的AndroidManifest.xml
文件,發現gradle
插件設置默認值爲false
是通過在處理AndroidManifest.xml
文件的時候,在其中自動插入 android:extractNativeLibs=“false"
來實現的。但是由於 android:extractNativeLibs
這個屬性是在 Android M(6.0)
引入的,所以如果項目中配置 minSdkVersion < 23
的話,gradle
插件是不會做這個自動插入的。
所以我們得出 extractNativeLibs
默認值的幾種情況
條件 | 默認值 |
---|---|
AGP < 3.6.0 || minSdkVersion < 23 | true |
AGP >=3.6.0 && minSdkVersion >= 23 | false |