针对不同的 GL 纹理创建多个 APK

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

在开发 Android 应用时,要充分利用 Google Play 上的多个 APK, 一定要从一开始就采取一些良好的做法,以免进一步 加入到开发过程中。本课将介绍如何创建应用的多个 APK 支持其他 OpenGL 纹理格式子集。您还将获得 使维护多 APK 代码库尽可能轻松。

确认您需要多个 APK

尝试创建适用于所有可用 Android 系统的应用时 您自然希望自己的应用在每一种设备上都能达到最佳的呈现效果,而不受其影响 事实上,它们并非都支持同一组 GL 纹理。你一开始好像觉得 支持多 APK 是最好的解决方案,但通常并非如此。使用单个 APK 而是提供了多 APK 开发者指南的一些实用信息, 只需一个 APK 即可完成此操作,包括如何检测支持的纹理 格式。根据您的具体情况,您可以将所有格式与 然后轻松选择要在运行时使用哪个模型。

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

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

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

制作您的需求图表

Android 开发者指南提供了一些实用的受支持纹理的便捷参考, supports-gl-texture 页面。此页还包含一些有关支持哪些手机(或手机系列)的提示 特定纹理格式。请注意,通常最好让您的某个 APK 支持 ETC1,因为支持 OpenGL ES 的所有 Android 设备都支持该纹理格式 2.0 规范。

由于大多数 Android 设备都支持多种纹理格式,因此您需要 优先顺序创建一个图表,其中包含您的应用要支持的所有格式。 联系。最左边的单元格的优先级最低(可能是 ETC1, 在性能和兼容性方面始终默认)。然后在图表中着色 代表一个 APK。

ETC1 ATI PowerVR

图表中的着色不仅可减少此指南的单色程度 - 它还具有 让团队内部的沟通变得更轻松:现在,您可以简单地用“蓝色”“绿色”或 “red”,而不是“支持 ETC1 纹理格式的那个”等。

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

无论您是修改现有 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 中列出的任一纹理格式, 该设备会被视为符合条件

关于 GL 纹理,最后一条规则很重要。也就是说,对于 例如,在同一应用中使用不同的 GL 格式时要非常谨慎。如果您 在 99% 的情况下使用 PowerVR 的情况,而将 ETC1 用于启动画面等...然后,您的清单文件 不一定表示支持这两种格式支持 ETC1 的设备 应用才会被认定为兼容,因此用户会下载您的应用,而用户则会看到一些令人紧张的崩溃 消息。常见的情况是,如果您使用多个 APK 专门用于 在基于 GL 纹理支持的不同设备上,每个 APK 将采用一种纹理格式。

这实际上使得纹理支持与其他两个多 APK 略有不同 尺寸、API 级别和屏幕尺寸任何给定设备都只有一个 API 级别和一个屏幕 而具体的支持范围则取决于 APK。对于纹理,APK 通常会 支持一种纹理,而设备会支持多种纹理。但对于同一个平台, 设备支持多个 APK,但解决方法是相同的:版本代码。

以几台设备为例,看看对于每种设备而言,有多少之前定义的 APK 设备。

FooPhone Nexus S Evo
ETC1 ETC1 ETC1
PowerVR ATI TC

假设 PowerVR 和 ATI 格式在可用时均优于 ETC1, 按照“版本号最高者优先”排序如果我们在每个 APK 中都设置了 versionCode 属性 如果红色 ≥ 绿色 ≥ 蓝色,则系统始终会选择红色和绿色,而非蓝色 如果有同时支持红色和绿色的设备, 就会选择红色

为了使您的所有 APK 分别进入不同的“轨道”,务必要有一个有效的版本代码 架构。您可以在我们的开发者指南的“版本代码”部分找到推荐的方案。开始时间 这组示例 APK 只涉及 3 个可能的维度之一, 将每个 APK 相隔 1000,然后以 1,000 为增量递增。相应版本代码可能类似如下:

蓝色: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-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" />
    ...

绿色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="2001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_AMD_compressed_ATC_texture" />
    ...

红色:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="3001" android:versionName="1.0" package="com.example.foo">
    <supports-gl-texture android:name="GL_IMG_texture_compression_pvrtc" />
    ...

检查发布前核对清单

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

  • 所有 APK 必须具有相同的软件包名称
  • 所有 APK 必须使用相同的证书签名
  • 请仔细检查您的清单过滤器是否存在冲突信息(仅支持 超大屏幕上的纸杯蛋糕不会被任何人看到)
  • 每个 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 定位到正确的设备。恭喜您大功告成了!