關於 extractNativeLibs 默認值的調研

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>

如何確認apkso是壓縮存儲的還是未壓縮存儲的呢,使用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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章