将 minSdkVersion 从 16 更改为 26 将发布的 APK 大小从 17 MB 增加到 39 MB
Changing minSdkVersion from 16 to 26 increased release APK size from 17 to 39 MB
我有一个相对较小且简单的应用程序,它总是生成一个 ~17 MB 的发布 APK 文件。前段时间我注意到 APK 大小增加到惊人的(对于这个应用程序)39 MB。我追踪了导致它的变化,结果发现相同的代码库,其中唯一的变化是 minSdkVersion
从 16 到 26 没有任何其他变化 导致 APK增加。
奇怪的是,当我解压 APK 时,解压后的目录占用了大约 40 MB 的磁盘空间。有一些变化,但都是很小的文件,就像26版少了一些布局,可以忽略不计。 40 MB 中最大的部分是包含 *.so 库的 lib 文件夹,总计 37 MB,但它们在两个 APK 版本中是相同的。 (该应用程序是使用 flutter build apk --release
构建的 Flutter 应用程序。)
我实际上不希望也不需要 minSdkVersion
为 26 并将恢复此更改,但我很好奇:
- 在 Android 的过程中发生了什么变化导致这两个
minSdkVersion
之间的大小增加如此显着?
- 这些 APK 在解压后如何大小几乎相同?似乎为
minSdkVersion
16 构建时的压缩要好得多?
- 如果解压缩目录的大小几乎相同,那么大小的增加对最终用户来说真的重要吗?他们需要下载 17 MB 还是 37 MB?为
minSdkVersion
26 构建的应用程序会在他们的设备上占用更多 space 吗?
根据 android:extractNativeLibs
上的文档,这是按预期工作的:
Whether or not the package installer extracts native libraries from the APK to the filesystem. If set to "false"
, then your native libraries must be page aligned and stored uncompressed in the APK. Although your APK might be larger, your application should load faster because the libraries are directly loaded from the APK at runtime. On the other hand, if set to "true"
, native libraries in the APK can be compressed. During installation, the installer decompresses the libraries, and the linker loads the decompressed libraries at runtime; in this case, the APK would be smaller, but installation time might be slightly longer.
The default value is "true"
if extractNativeLibs
is not configured in AndroidManifest.xml
. However, when building your app using Android Gradle plugin 3.6.0 or higher, this property is reset to "false"
if it is NOT configured in AndroidManifest.xml
and minSdkVersion >= 23
.
因此,您通过不提取本机库来获得运行时性能,从而获得更好的用户体验。由于系统不需要解压缩 .so
文件,因此您实际上也在用户设备上保存了 space。
如 Reduce your app size 中所述:
When building the release version of your app, package uncompressed .so
files in the APK by setting android:extractNativeLibs="false"
in the <application>
element of your app's manifest. Disabling this flag prevents PackageManager
from copying .so
files from the APK to the filesystem during installation and has the added benefit of making updates of your app smaller.
因此,虽然 APK 大小起初较大,但后续更新实际上要小得多。这是因为 Google Play 商店在进行应用程序升级时仅自动下载 APK 之间的差异 - 通过存储未压缩的 .so
文件,此差异明显较小,因为额外的压缩通常会完全改变 .so
文件,而不是只更改实际更改的部分。
我有一个相对较小且简单的应用程序,它总是生成一个 ~17 MB 的发布 APK 文件。前段时间我注意到 APK 大小增加到惊人的(对于这个应用程序)39 MB。我追踪了导致它的变化,结果发现相同的代码库,其中唯一的变化是 minSdkVersion
从 16 到 26 没有任何其他变化 导致 APK增加。
奇怪的是,当我解压 APK 时,解压后的目录占用了大约 40 MB 的磁盘空间。有一些变化,但都是很小的文件,就像26版少了一些布局,可以忽略不计。 40 MB 中最大的部分是包含 *.so 库的 lib 文件夹,总计 37 MB,但它们在两个 APK 版本中是相同的。 (该应用程序是使用 flutter build apk --release
构建的 Flutter 应用程序。)
我实际上不希望也不需要 minSdkVersion
为 26 并将恢复此更改,但我很好奇:
- 在 Android 的过程中发生了什么变化导致这两个
minSdkVersion
之间的大小增加如此显着? - 这些 APK 在解压后如何大小几乎相同?似乎为
minSdkVersion
16 构建时的压缩要好得多? - 如果解压缩目录的大小几乎相同,那么大小的增加对最终用户来说真的重要吗?他们需要下载 17 MB 还是 37 MB?为
minSdkVersion
26 构建的应用程序会在他们的设备上占用更多 space 吗?
根据 android:extractNativeLibs
上的文档,这是按预期工作的:
Whether or not the package installer extracts native libraries from the APK to the filesystem. If set to
"false"
, then your native libraries must be page aligned and stored uncompressed in the APK. Although your APK might be larger, your application should load faster because the libraries are directly loaded from the APK at runtime. On the other hand, if set to"true"
, native libraries in the APK can be compressed. During installation, the installer decompresses the libraries, and the linker loads the decompressed libraries at runtime; in this case, the APK would be smaller, but installation time might be slightly longer.The default value is
"true"
ifextractNativeLibs
is not configured inAndroidManifest.xml
. However, when building your app using Android Gradle plugin 3.6.0 or higher, this property is reset to"false"
if it is NOT configured inAndroidManifest.xml
andminSdkVersion >= 23
.
因此,您通过不提取本机库来获得运行时性能,从而获得更好的用户体验。由于系统不需要解压缩 .so
文件,因此您实际上也在用户设备上保存了 space。
如 Reduce your app size 中所述:
When building the release version of your app, package uncompressed
.so
files in the APK by settingandroid:extractNativeLibs="false"
in the<application>
element of your app's manifest. Disabling this flag preventsPackageManager
from copying.so
files from the APK to the filesystem during installation and has the added benefit of making updates of your app smaller.
因此,虽然 APK 大小起初较大,但后续更新实际上要小得多。这是因为 Google Play 商店在进行应用程序升级时仅自动下载 APK 之间的差异 - 通过存储未压缩的 .so
文件,此差异明显较小,因为额外的压缩通常会完全改变 .so
文件,而不是只更改实际更改的部分。