您可以为配置 APK 设置 build,从而缩减您的应用在每个用户设备上的 APK 大小。这会将应用的 DEX 代码以及与设备无关的资源放在一个 APK 中,并将每组依赖于设备的原生代码和资源放在单独的 APK 中。然后,设备只会请求运行您的应用所需的 APK。这样,您就可以在创建的 APK 中包含适用于特定屏幕密度、ABI 和/或语言的文件,从而缩减应用的下载大小。
配置 APK 类似于多 APK,但有一些重要的区别:
- 目前,“多 APK”仅适用于安装式应用,而配置 APK 则只适用于免安装应用。
- 采用“多 APK”时,系统会为每个属性组合构建一个 APK。而对于配置 APK,则会有一个基础 APK,其中包含与设备无关的 DEX 代码,还有一个 APK 用于各个可变维度的每个值(即每个受支持的语言、密度或 ABI 都有一个对应的 APK)。举例来说,假设因密度和语言而异的某个应用支持四种密度和三种语言。采用“多 APK”时,开发者会上传 3 * 4 = 12 个 APK。而对于配置 APK,他们则会上传 1(基础)+ 3 + 4 = 8 个 APK。采用“多 APK”时,任何特定设备都只会获得一个 APK。对于配置 APK,设备会获得一个基础 APK,另外可能还会获得每个受支持维度(目前为语言、密度和 ABI)的一个或多个资源 APK。
- 采用“多 APK”,您可以使用版本代码从给定设备的多个兼容 APK 中进行选择。配置 APK 则不使用开发者指定的排序。排序取决于可用 APK 的定位。
-
配置 APK 支持新的定位维度
language
。 “多 APK”则不支持。
前提条件
在为配置 APK 设置 build 之前,请查看以下步骤,确保您的 build 已准备就绪,并验证您在 Android Studio 中是否具备所需的工具配置:
- 将您的免安装应用模块的最低 SDK 版本设置为 21 或更高
- 使用 Android Studio 3.0 或更高版本
为配置 APK 设置 build
如需根据语言为您的配置 APK 设置 build,请在功能模块的 splits
块中添加语言块,并在 android
块中指定 generatePureSplits = true
。如需详细了解如何配置 splits
块,请参阅针对多 APK 配置 build。
android { ... generatePureSplits = true splits { abi { enable = true } density { enable = true } language { enable = true include "es-rMX", "zh", "en" } } }
语言值采用提供备用资源中所述的格式。
传送配置 APK
与采用“多 APK”不同,开发者不会为多个等效配置 APK 定义排序。那么,Play 如何决定要传送哪个 APK?
对于 ABI,Play 会按照对所有设备都一样的固定排序从兼容的 APK 中进行选择。该排序为 x86_64
、x86
、mips64
、mips
、arm64-v8a
、armeabi-v7a
、armeabi
。举例来说,如果设备同时支持 x86
和 armeabi-v7a
,并且两者都有相应的 APK,则会传送 x86
APK(以及基础 APK)。
对于密度,Play 会在可用的 APK 中选择最接近设备密度的 APK。
按语言选择 APK 更为复杂。
关于语言定位的特殊问题
有人可能认为 Play 会尝试完全匹配用户的语言区域。如果是 en-GB
,则可能传送定向到 en-GB
的 APK(如果可用),否则回退到 en
。这种方法存在两个问题:
-
不要求配置 APK 必须包含每个字符串的翻译,就像
strings.xml
文件没有这种要求一样。可以接受为仅有的一个字符串或少量字符串添加语言(这种情况甚至很常见)。例如,en/strings.xml
可能包含“car”和“truck”,而en-rGB/strings.xml
则可能只包含“lorry”。因此,正如任何设备所必需的的翻译集可能位于多个strings.xml
文件中一样,这些文件可能包含在多个配置 APK 中。 -
Android 设备具有变化多样的回退图表。Android 版本可以更改回退图表(请参阅语言和语言区域指南)。
此外,原始设备制造商 (OEM) 还会自定义回退顺序(例如,
“zh”
指的是“zh-TW”
还是“zh-CN”
取决于 OEM)。Play 并不总是知道发出请求的设备使用了什么回退顺序。
为了解决这些问题,Play 会传送满足下述条件的所有配置 APK:它们都定位到语言子标签(短划线前面的部分)与用户所选语言区域相匹配的语言。 这依赖于观察到的一个现象,即回退算法通常不会跨语言回退。 示例如下:
用户的语言区域为 de-CH
。
可用的 APK 为 de
、de-CH
、de-AT
和 fr
。
Play 会传送 de
、de-CH
和 de-AT
,但不传送 fr
。
在有些情况下,尽管语言子标签不匹配(例如 fil
/tag
),也应将语言组合起来,Play 也会处理这种熟知的情况。
Play 会在传送时完成组合操作,无需开发者执行任何操作。
问题排查和常见问题解答
- Gradle 未生成配置 APK,而是显示了以下消息
Variant ..., MinSdkVersion 18 is too low (<21) to support pure splits, reverting to full APKs
在免安装应用模块的 build.gradle 文件中指定
minSdkVersion = 21
- Gradle 插件显示以下消息:
> Configure project :base Pure splits are not supported by PlayStore yet.
这是一个已知问题。请忽略此消息。
- 配置 APK 对 4MB 的限制有何影响?
功能大小的计算方式是以下三项之和:功能 APK 大小,基础功能 APK 大小以及可能传送到设备的最大配置 APK 集。例如,如果某个功能的基础 APK 有 3 个语言 APK 和 2 个密度 APK,功能 APK 有 2 个密度 APK,那么功能 APK 大小加上基础 APK 大小,再加上基础 APK 的最大语言和最大密度 APK,以及功能 APK 的最大密度 APK,即得出最后的功能大小。
已知问题
- 对于某些增量构建,Gradle 无法构建 ABI APK(https://issuetracker.google.com/69680755)。这个问题可以通过清理并重新构建来解决。
-
目前,构建工具无法创建多维配置 APK。
例如,针对采用法语的
xhdpi
设备,某个项目可能在res/drawable-fr-xhdpi
中包含一项资源,但 Gradle 无法将此类资源放入配置 APK 中。任何此类资源都会放入基础或功能 APK 中。