最近编译一个apk,minSdkVersion 调到23 发现apk体积暴增了一倍, minSdkVersion 19 apk体积 6M 改成 23 体积变为 12M.
解决办法:
AndroidManifest.xml
<application
android:extractNativeLibs=”true”
>
原因探究:
如果 minSdkVersion 为 23+,开发人员也没有手动设置 android:extractNativeLibs=”true”,系统会在清单中自动注入 android:extractNativeLibs=”false”。
通过 Google 搜索,终于有文章将原因指向了 <application> 节点下的 extractNativeLibs 属性,紧接着在官方文档中找到了关于 android:extractNativeLibs 的描述。
属性 描述
android:extractNativeLibs 软件包安装程序是否将原生库从 APK 提取到文件系统。如果设为 false,则原生库必须保持页面对齐状态并以未压缩的形式存储在 APK 中。无需更改代码,因为链接器在运行时直接从 APK 加载库。默认值为 “true”。
这段描述的意思是:如果 extractNativeLibs 属性的值为 false,那么 APK 在打包签名过程中 so 库会保持页面对齐状态并以未压缩的形式被打包到签名包中,并且在 APK 安装的过程也不会将应用内的 so 库提取到系统中。因为 so 库没有被压缩,所以调用 so 库的时候也是直接从 APK 中进行加载。如果 extractNativeLibs 属性的值为 true,那么 APK 在打包签名过程中 so 库会以压缩的形式被打包到签名包中,并且会在 APK 安装的过程中将应用内的 so 库提取到系统中,调用 so 库的时候会从系统的提取目录中进行加载。
如果 extractNativeLibs 属性值为 false 有什么好处呢?可以节省用户手机的空间。因为应用和系统共同持有一份 so 库,但由于 so 库在打包过程中没有被压缩,会造成签名包体积增大。如果 extractNativeLibs 属性值为 true,那么 so 库会被压缩打包到应用中,优点是 APK 体积会很小;但缺点也显而易见,安装后的应用会持有一份压缩的 so 库,系统会持有一份解压后的 so 库,那份无法被调用的压缩 so 库会占用用户的手机空间。