关于 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章