将android:extractNativeLibs=false设置为减少应用程序大小。

24

我不确定我是否理解正确。看起来它正在做相反的事情。如果我保持标志android:extractNativeLibs设置为true,应用程序会占用用户空间约70MB(是的 ...),但如果我将此标志设置为false,则安装在设备上的应用程序大小会跳到大约95MB左右。所以我不确定用户是否会欣赏这一点。


你有什么问题?我不明白。 - user7462841
2
这实际上是正确的,它将减少应用程序的运行时内存,因为它不会将so文件复制到系统中。.so文件将直接从apk加载。此外,请检查是否可以禁用此处提到的调试符号。https://developer.android.com/topic/performance/reduce-apk-size.html#reduce-code - siva
谢谢,我会尝试的。 - egoldx
3个回答

63
这有点棘手。当extractNativeLibs设置为false时,您的APK大小将会更大。
旧的行为
当extractNativeLibs设置为true(默认)或未添加到清单中时,您的本机库可以被压缩存储在APK中。Package Manager在安装过程中提取它们,并将副本放在/data/app/中。因此,本地库有两个副本 - 一个是APK中的压缩版本,另一个是/data/app/中的未压缩版本。
这种方法具有以下优点:
- APK大小较小,因为库被压缩了。 缺点:
- 安装大小增加(“存储”或“磁盘”在Settings => Apps中),因为除了APK之外,提取的本地库还占用了磁盘空间 - 安装时间更长 - Google Play的优化较少,例如生成更新补丁时
新行为
Google在Marshmallow(Android 6)中引入的新方法可以通过将extractNativeLibs设置为“false”来启用。它期望将库以未压缩的方式存储在APK中(STORE方法)并进行zip对齐。在安装过程中无需提取它们。在应用程序启动时,库可以直接从APK中加载(memmapped)。
优点:
- 安装大小减小(“存储”或“磁盘”在Settings => Apps中),因为无需提取库。基本上,占用的空间通常比APK大小略大 - 来自Google Play的下载大小没有增加,因为它在APK之上使用自己的压缩 - Google Play通过优化的更新补丁生成结果更新大小更小。如果您更新本地库,则压缩版本将具有巨大的差异,导致较大的补丁,而未压缩库的补丁会相对较小。
缺点:
- APK大小更大,因为本机库未被压缩

预计地,我并没有发现两个选项在加载性能上有显著的区别。

结论

extractNativeLibs="false"选项可能适用于以下情况:

  • 您不关心APK的大小 - 它可以远远低于100 Mb的极限或者您已经使用扩展文件(OBB)并且可以处理APK大小的增加。
  • 您关心应用在Google Play中的更新大小。
  • 您的本地库不是很大。

例如,对于使用Unity制作的游戏,由于其较大的本地库,这个选项几乎不适用。

更新:Android App Bundles

Android App Bundle是由Google Play宣布的一种新的分发机制,更多详情请参见官方网站https://developer.android.com/platform/technology/app-bundle/https://developer.android.com/guide/app-bundle/

它具有显着优势,其中最重要的是150 Mb的最大大小限制。重要提示:这是下载大小,而不是应用程序包本身或生成的APK的大小。(APK由Play生成并在设备上动态交付,更多详情可在官方的Android资源上了解到如何工作)。

构建AAB时,它默认将extractNativeLibs标志设置为"false"。但是,由于Google Play在交付给最终设备的APK上应用压缩,这并不影响下载大小。这意味着该标志仅在Android App Bundles的情况下带来好处 - 安装更快,几乎没有施加向最大大小限制施加压力的额外成本,占用磁盘空间更少。

然而令人困惑的是,当你接近150 MB的限制时如何计算下载大小,因为AAB大小并不代表下载大小。在中有一个特殊的命令来计算它,详情请参阅https://developer.android.com/studio/command-line/bundletool#measure_size或直接上传到Play。如果你的AAB远低于150 MB,那就没必要担心了。

(更新:使用150 MB的应用程序包大小限制,而不是500 MB;显然,在开发人员预览版中提供了500 MB,但现在已经不公开了)。


1
附加行为:安装将失败并显示“INSTALL_FAILED_INVALID_APK”消息,并显示其他干扰本地调试的症状(例如本地代码中的断点不起作用),偶尔会出现这种情况。 - Toris
1
Android App Bundles的Bundle工具可以提供APK下载大小估算。请参见:https://developer.android.com/studio/command-line/bundletool#measure_size - Chris Li
1
@Over17 我认为这只对签名应用程序有影响。 - android developer
你谈论“旧”和“新”的行为,并将新的行为称为与Marshmallow一起提供的行为。但是我只看到自Marshmallow以来可用的extractNativeLibs。我如何在Lollipop和更早版本上使用它? - Edw590
1
@DADi590,很抱歉你做不到。这是包管理器的一个特性(不解压库文件),以及加载器的一个特性(允许直接从APK中加载未压缩的库文件)。如果操作系统不支持,你就无能为力了。你可以尝试模拟直接从APK中加载,但操作系统仍会解压库文件,所以这没有意义。 - Over17
显示剩余5条评论

11

extractNativeLibs="false" 如果你的 APK 包含多个 ABI,可能会适得其反。假设你正在使用一个每个 ABI 都有 10 MB 大小的库,并且可以压缩到 5 MB。如果你有 3 个 ABI,则结果如下:

extractNativeLibs="true"

APK:       15 MB (3 x 5 MB)
Extracted: 10 MB
Total:     25 MB

extractNativeLibs="false":

APK:       30 MB (3 x 10 MB)
Extracted:  0 MB
Total:     30 MB

截至2019年,缓解此问题的推荐方法是使用Android App Bundle格式。


2
如果您拆分apk或使用新的.aab捆绑格式,则情况并非如此。 - Gil

2

但是,这需要一些重要的先决条件才能实现,这就是事情变得更加复杂的地方:

  • APK中的 .so 文件不能被压缩 - 它们必须被存储。
  • .so 文件必须使用 zipalign -p 4 进行页面对齐

更新:以下部分仅适用于Android Studio版本2.1及以下版本。 从Android Studio 2.2 Preview 2和最新版本的构建工具开始,构建过程将自动将本机库未经压缩和页面对齐存储在APK中。

更多信息: 链接

更新:如果您手动签署应用程序,则在何时调用zipalign很重要。

注意:您必须在应用程序构建过程中的两个特定点之一使用zipalign,具体取决于您使用的应用程序签名工具:

  • 如果您使用apksigner,则必须仅在签署APK文件之前执行zipalign。如果您使用apksigner签署APK并对APK进行进一步更改,其签名将无效。
  • 如果您使用jarsigner,则必须仅在签署APK文件之后执行zipalign。

来源:zipalign | Android Developers

Android 6+将阻止您安装未对齐的带有未压缩本机库的APK。旧版Android不会关心并始终提取本机库。


我明白,但问题是,我希望使用android:extractNativeLibs=”false”能够使总大小更小,但事实上相反 - 它大约增加了~25MB。在Android 7.1.1上进行了测试。 - egoldx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接