我有一个相对较小且简单的应用程序,它始终生成约 17 MB 的发布 APK 文件。不久前,我注意到 APK 大小增加到了惊人的(对于这个应用程序)39 MB。我追踪了导致它的更改,结果发现相同的代码库,其中唯一的更改是
minSdkVersion
从 16 到 26 没有任何其他更改 导致 APK 增加。
奇怪的是,当我解压 APK 时,解压后的目录在磁盘上占用了约 40 MB 的空间。有一些更改,但所有更改都在非常小的文件中,就像 26 版本中缺少一些布局一样,可以忽略不计。 40 MB 中最大的部分是 lib 文件夹,其中包含 *.so 库,总计 37 MB,但它们在两个 APK 版本中是相同的。 (该应用程序是使用
flutter build apk --release
构建的 Flutter 应用程序。)
我实际上并不希望也不需要
minSdkVersion
为 26,并且会恢复此更改,但我很好奇:
minSdkVersion
之间的大小急剧增加?minSdkVersion
16 时的压缩要好得多?minSdkVersion
26 构建的应用程序会占用他们设备上的更多空间吗?android:extractNativeLibs
上的文档按预期工作:
软件包安装程序是否将本机库从 APK 提取到文件系统。如果设置为
,则您的本机库必须页面对齐并以未压缩的方式存储在 APK 中。 虽然您的 APK 可能更大,但您的应用程序应该加载得更快,因为库是在运行时直接从 APK 加载的。 另一方面,如果设置为"false"
,则可以压缩 APK 中的本机库。安装过程中,安装程序解压库,链接器在运行时加载解压后的库;在这种情况下,APK 会较小,但安装时间可能会稍长。 如果"true"
"true"
中未配置extractNativeLibs
,则默认值为AndroidManifest.xml
。但是,当使用Android Gradle 插件 3.6.0 或更高版本构建应用程序时,如果在"false"
和中配置了 NOT,则此属性将重置为AndroidManifest.xml
。 因此,您可以通过不提取本机库来获得运行时性能,从而获得更好的用户体验。由于系统不需要解压缩minSdkVersion >= 23
.so
文件,因此实际上也节省了用户设备上的空间。
如减小应用程序大小构建应用程序的发布版本时,通过在应用程序清单的.so
元素中设置
来将未压缩的android:extractNativeLibs="false"
文件打包到 APK 中。禁用此标志可防止<application>
在安装过程中将PackageManager
文件从 APK 复制到文件系统,并具有使应用程序更新更小的额外好处。 因此,虽然 APK 大小一开始较大,但后续更新实际上要小得多。这是因为 Google Play 商店在进行应用程序升级时仅自动下载 APK 之间的差异 - 通过存储未压缩的.so
.so
文件,此差异会明显更小,因为额外的压缩通常会完全更改
.so
文件,而不是仅仅更改更改实际更改的部分。。因此,Android官方文档建议将其添加到应用程序级别的build.gradle中
android {
packagingOptions {
jniLibs {
useLegacyPackaging true // Enabling flag to compress JNI Libs to reduce APK size Ref: https://developer.android.com/studio/releases/gradle-plugin#compress-native-libs-dsl
}
}
}
添加上述代码片段后,apk 大小与早期版本相比减小了