针对不同的屏幕尺寸创建多个 APK

如果您将应用发布到 Google Play,您应构建并上传 Android App Bundle 文件。当您执行此操作时,Google Play 会针对每个用户的设备配置自动生成并提供经过优化的 APK,以便他们仅下载运行您的应用所需的代码和资源。如果您不将应用发布到 Google Play,那么发布多个 APK 很有用,但您必须自行构建和管理每个 APK 并为其签名。

如果您要开发 Android 应用,以便充分利用 Google Play 上的多个 APK, 一定要从一开始就采取一些良好的做法, 进行深入的分析本课将介绍如何为 应用,每个应用涵盖不同大小的屏幕尺寸。您还将获得 使维护多 APK 代码库尽可能轻松。

确认您需要多个 APK

在尝试创建适用于多种尺寸的 Android 设备的应用时, 您自然希望自己的应用能够充分利用大屏幕设备上的所有可用空间 同时丝毫不会影响兼容性或易用性。乍一看,这似乎是 尽管支持多 APK 是最佳解决方案,但通常并非如此。使用单个 APK 而是提供了多 APK 开发者指南的一些实用信息, 只需使用单个 APK 即可完成此操作,包括使用我们的支持库。您还应阅读 支持多种屏幕的指南、 甚至还有一个支持库 可以使用 Android SDK 下载,这让您可以在 Honeycomb 之前的设备上使用 fragment( 在单个 APK 中实现多屏幕支持要简单得多)。

如果您可以管理它,将应用限制在单个 APK 有几个好处, 包括:

  • 发布和测试更加轻松
  • 只需要维护一个代码库
  • 您的应用可以适应设备配置的变化
  • 可以跨设备执行应用恢复
  • 您不必担心市场偏好和“升级”带来的行为从一个 APK 复制到 或者哪个 APK 与哪类设备搭配使用

本课程的其余部分假定您已经了解了相关主题,并认真学习了 并且确定多 APK 是适合您的应用的正确途径 应用。

制作您的需求图表

首先,创建一个简单的图表来快速确定您需要多少个 APK 以及在什么屏幕上使用 每个 APK 涵盖的大小幸运的是,你可以轻松快捷地绘制出需求图表 以供日后参考从表示不同屏幕尺寸的一行单元格开始着手 适用于 Android 平台。

small normal large xlarge

现在只需在图表中着色,使每种颜色代表一个 APK。这里举一个例子来说明 可能会将每个 APK 应用于特定范围的屏幕尺寸。

small normal large 特大

根据你的需求,你还可以准备两个 APK:“small 和其他所有 APK”或“xlarge and 其他所有内容”。在图表中着色也可以让团队内部的沟通变得更轻松。您可以 现在,无论有多少不同的屏幕类型,只需将每个 APK 称为“蓝色”“绿色”或“红色” 。

将所有通用代码和资源放在一个库项目中

无论您是修改现有 Android 应用,还是从头开始构建应用, 你应该对代码库做的第一件事,也是迄今为止最重要的。全部 放入库项目中的字符串只需更新一次(想想已本地化的字符串, 颜色主题、在共享代码中修复的 bug),从而缩短开发时间并减少 出现原本可以很容易避免的错误的可能性。

注意:尽管有关如何创建 “添加库项目”不在本课程的讨论范围之内,您可以 阅读创建 Android 库

如果您要将现有应用转换为使用多个 APK 支持, 在您的代码库中搜索每个本地化的字符串文件、值列表、主题 在不同 APK 之间保持不变的颜色、菜单图标和布局, 全部都在库项目中不会发生太大变化的代码应该 也会显示在库项目中您很可能会发现 类将一两个方法从 APK 添加到 APK。

另一方面,如果您要从头开始创建应用,请尝试 在库项目中编写代码,然后再只将其移至 (如果需要)。从长远来看,这比添加到 又在几个月后,试图弄清楚这个 blob 能否上移 无需调整任何东西

创建新的 APK 项目

您应该为要发布的每个 APK 单独创建一个 Android 项目。简单 请将库项目和所有相关的 APK 项目放在同一个父文件夹下。 另请注意,每个 APK 必须具有相同的软件包名称,尽管它们不一定 需要与库共享软件包名称如果您有 3 个遵循 scheme 的 APK 则您的根目录可能如下所示:

alexlucas:~/code/multi-apks-root$ ls
foo-blue
foo-green
foo-lib
foo-red

项目创建完毕后,请将库项目作为引用添加到各个 APK 项目中。如果 在库项目中定义启动 Activity,并在 APK 中扩展该 Activity 项目。在库项目中定义启动 activity 后,您便可以将所有 并在一个位置集中进行应用初始化 重新实施“通用”例如初始化 Google Analytics、运行许可检查,以及 在不同 APK 之间变化不大的初始化过程。

调整清单

当用户通过 Google Play 下载使用多个 APK 的应用时,正确的 使用两条简单的规则来选择要使用的 APK:

  • 清单必须显示特定的 APK 符合条件
  • 在符合条件的 APK 中,选择版本最高的一个

我们以上文所述的一组多 APK 为例,假设每个 APK 已设置为支持所有大于其“目标”的屏幕尺寸屏幕尺寸单独来看, 每个 APK 的可能范围如下所示:

small normal large xlarge
small normal large xlarge
small normal large 特大

不过,如果使用“版本最高的一个”,那么如果我们在 每个 APK 的红色 ≥ 绿色 ≥ 蓝色,则该图表实际上可收起为:

small normal large 特大

现在,让我们进一步假设红色 APK 有一些另外 2 种颜色的 APK 所没有的要求。通过 Android 的 Google Play 上的过滤器页面 开发者指南完整列出了可能的问题根源。举例来说,我们假设 红色的摄像头需要使用前置摄像头。事实上,红色 APK 的全部意义就在于使用 可用的屏幕空间,让您用前置摄像头轻松畅享娱乐内容。但后来发现 并非所有特大屏幕设备都有前置摄像头!这太糟糕了!

幸运的是,如果用户在此类设备上浏览 Google Play,Google Play 会查看 看到红色的“前置摄像头”列为一项要求,然后静默地忽略它, 后来判定红色和该设备在数字天堂中是不匹配的。然后,系统就会显示 绿色不仅兼容特大设备,而且不关心是否有 前置摄像头!用户仍可从 Google Play 下载该应用,因为 尽管发生了前置摄像头的小意外,但仍然有 APK 可以支持这个特定的屏幕 。

为了便于区分各个 APK,请务必提供有效的版本代码 架构。您可以在 我们的开发者指南由于这组示例 APK 只处理 3 个可能的 那么将每个 APK 隔开 1000,然后在此基础上递增就足够了。本次 可能如下所示:

蓝色:1001, 1002, 1003, 1004...
绿色:2001, 2002, 2003, 2004...
红色:3001, 3002, 3003, 3004...

综上所述,您的 Android 清单可能类似于 以下:

蓝色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1001" android:versionName="1.0" package="com.example.foo">
    <supports-screens android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

绿色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="true"
        android:xlargeScreens="true" />
    ...

红色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-screens android:smallScreens="false"
        android:normalScreens="false"
        android:largeScreens="false"
        android:xlargeScreens="true" />
    ...

请注意,从技术上讲,支持多个 APK 代码或 compatible-screens 代码通常首选 Supports-screens 最好不要在同一个清单中同时使用这两个标记它 这会不必要地增加复杂性,并增加出错的几率。 另请注意,与使用默认值(小 normal 始终为 true),则清单会明确设置 各种屏幕尺寸这可以为您省掉今后的麻烦。例如,一个包含 目标 SDK 版本低于9 将“xlarge”自动设置为 false,因为该尺寸尚不存在。 因此请明确设置值!

检查发布前核对清单

在上传到 Google Play 之前,请仔细检查以下各项内容。请注意 并非适用于所有 APK 的详尽核对清单 正在上传到 Google Play 的应用。

  • 所有 APK 必须具有相同的软件包名称
  • 所有 APK 必须使用相同的证书签名
  • 您希望 APK 支持的每种屏幕尺寸都在清单中被设为 true,各种屏幕尺寸 则设为 false。
  • 请仔细检查您的清单过滤器是否存在冲突信息(仅支持 超大屏幕上的纸杯蛋糕不会被任何人看到)
  • 每个 APK 的清单必须至少在一个受支持的屏幕、OpenGL 纹理或 平台版本
  • 尝试在至少一个设备上测试所有 APK。除此之外,你还有 企业中的可自定义设备模拟器,可放置在您的开发机器上。您可以尽情地测试!

此外,还应在将经过编译的 APK 推送到市场之前对其进行检查,以确保 以防您的应用在 Google Play 上无法展示。这其实很简单,只需使用 “aapt”工具。Aapt(Android 资源打包工具)是用于创建和 打包 Android 应用,这也是检查它们的便捷工具。

>aapt dump badging
package: name='com.example.hello' versionCode='1' versionName='1.0'
sdkVersion:'11'
uses-permission:'android.permission.SEND_SMS'
application-label:'Hello'
application-icon-120:'res/drawable-ldpi/icon.png'
application-icon-160:'res/drawable-mdpi/icon.png'
application-icon-240:'res/drawable-hdpi/icon.png'
application: label='Hello' icon='res/drawable-mdpi/icon.png'
launchable-activity: name='com.example.hello.HelloActivity'  label='Hello' icon=''
uses-feature:'android.hardware.telephony'
uses-feature:'android.hardware.touchscreen'
main
supports-screens: 'xlarge'
supports-any-density: 'true'
locales: '--_--'
densities: '120' '160' '240'

检查 aapt 输出时,请务必检查并确保 Support-screens 和 compatible-screens,并且没有意外的“uses-feature”价值 因您在清单中设置的权限而添加的。在上面的示例中,APK 对大多数设备(如果不是所有设备)不可见。

为什么?添加必要的 SEND_SMS 权限时,就隐式添加了 android.hardware.telephony 功能要求。由于大多数(如果不是所有)特大设备都是没有电话硬件的平板电脑,因此 Google Play 会在这些情况下过滤掉此 APK,直到未来出现既能报告为特大屏幕尺寸又拥有电话硬件的设备。

幸运的是,您只需将以下内容添加到 清单:

<uses-feature android:name="android.hardware.telephony" android:required="false" />

此外,还隐式添加了 android.hardware.touchscreen 要求。如果您希望在不属于触摸屏设备的电视上看到您的 APK,则应将以下内容添加到清单中:

<uses-feature android:name="android.hardware.touchscreen" android:required="false" />

完成发布前核对清单后,就可以将您的 APK 上传到 Google Play。 该应用可能要过一会儿才会在 Google Play 中显示 执行最后一项检查。将该应用下载到您可能拥有的所有测试设备上 APK 定位到的目标设备。

有关在 Google Play 上发布多个 APK 的详情,请阅读 多 APK 支持