迁移到 Android 8.0

Android 8.0(API 级别 26)引入了行为变更以及您的应用中可加以利用的新功能和 API。本文概述了将应用迁移到 Android 8.0 的两个关键阶段的步骤:

  1. 确保与 Android 8.0 兼容

    验证您的应用是否能够在新版本的平台上全功能运行。在此阶段,您不需要使用新的 API,也不需要更改应用的 targetSdkVersion,但可能需要进行一些细微的更改。

  2. 更新您的目标版本并使用 Android 8.0 功能

    当您准备好利用平台的新功能时,请将 targetSdkVersion 更新为 26,验证应用是否继续按预期运行,然后开始使用新 API。

确保与 Android 8.0 兼容

此处的目标是确保您的现有应用在 Android 8.0(API 级别 26)上照常运行。由于一些平台变化可能会影响应用的行为方式,因此可能需要进行一些调整,但您不需要使用新的 API 或更改 targetSdkVersion

分步确保与 Android 8.0 兼容

准备一台搭载 Android 8.0 的设备

  • 如果您有一台兼容设备(Pixel、Pixel XL、Pixel C、Nexus 5X、Nexus 6P 或 Nexus Player),请按照说明将映像刷入设备
  • 或下载适用于 Android 模拟器的 Android 8.0 系统映像。它在 Android 8.0 下的 SDK 管理器中已列为 Google API Intel x86 Atom System Image

    注意:Android 8.0 系统映像可从 Android Studio 3.0 及更高版本下载。 如需了解详情,请参阅下面一节以获取 Android 8.0 SDK

执行兼容性测试

在大多数情况下,测试应用与 Android 8.0(API 级别 26)的兼容性与您准备发布应用时执行的测试属于同一类型。这时有必要回顾一下核心应用质量指南测试最佳实践

不过,测试的另一个方面是:Android 8.0 对 Android 平台引入了更改,即使您不更改 targetSdkVersion,仍可能会影响应用的行为或使应用完全崩溃。因此,您必须回顾表 1 中的关键变化,并对任何为适应这些变化而实现的修复进行测试。

表 1. 对在 Android 8.0 设备上运行的所有应用都有影响的关键变化。

更改 摘要 其他参考文档
后台位置更新频率下降 如果您的应用从后台服务接收位置信息更新,则与旧版本 Android 相比,它在 Android 8.0(API 级别 26)上接收更新的频率较低。具体地讲,后台服务接收位置更新的频率不能超过每小时几次。不过,当应用位于前台时,位置更新频率不变。 后台位置信息限制
net.hostname 已不再受支持 查询 net.hostname 系统属性返回的结果为 null。
send(DatagramPacket) 引发新异常 如果之前执行的 connect(InetAddress, int) 方法失败,send(DatagramPacket) 方法会抛出 SocketException 行为变更:网络连接和 HTTP(S) 连接
AbstractCollection 方法中的正确 NullPointerException AbstractCollection.removeAll(null)AbstractCollection.retainAll(null) 现在始终抛出 NullPointerException;以前,当集合为空时不会抛出 NullPointerException。此更改使行为与文档保持一致。 行为变更:收集处理
Currency.getDisplayName(null) 中的正确 NullPointerException 调用 Currency.getDisplayName(null) 会抛出 NullPointerException 行为变更:语言区域和国际化

如需查看 Android 8.0(API 级别 26)中更详尽的行为变更列表,另请参阅 Android 8.0 行为变更

更新您的目标版本并使用 Android 8.0 功能

本部分说明了如何通过将 targetSdkVersion 更新为 26 并增加 Android 8.0 中提供的新功能来实现对 Android 8.0(API 级别 26)的全面支持。

除了提供新的 API 之外,当您将 targetSdkVersion 更新为 26 时,Android 8.0 还引入了一些行为变更。由于某些行为变更可能需要更改代码以免出现故障,因此,您应先查看所有涉及以 Android 8.0 为目标平台的应用的行为变更,了解更改 targetSdkVersion 后您的应用会受到哪些影响。

注意:上述旨在确保平台兼容性的步骤是将应用以 Android 8.0 为目标平台的先决条件,因此请务必先完成这些步骤。

逐步更新目标版本并使用 Android 8.0 功能

获取 Android 8.0 SDK

您可以使用最新版 Android Studio(建议使用 Android Studio 3.0 及更高版本)获取 SDK 软件包,以便利用 Android 8.0(API 级别 26)构建应用。 Android Studio 3.0 及更高版本包含一些工具,可帮助您使用 Android 8.0 功能,例如自适应图标可下载的字体。 如果您暂时不需要这些功能,则可以使用稳定版 Android Studio 2.3.3 通过 Android 8.0 构建应用并使用新 API。

如需设置任一版本的 Android Studio,请按以下步骤操作:

  1. 启动 Android Studio,然后依次点击 Tools > SDK Manager 打开 SDK 管理器。
  2. SDK Platforms 标签页中,选中 Show Package Details。在 Android 8.0 Preview 下方,选中以下各项:
    • Android SDK 平台 26
    • Google APIs Intel x86 Atom System Image(只需在使用模拟器时选中)
  3. 切换到 SDK Tools 标签页,选中所有已提供更新的项(点击每个显示破折号 的复选框)。这应包括以下必需项的最新版本:
    • Android SDK Build-Tools 26.0.0
    • Android SDK Platform-Tools 26.0.0
    • Android 模拟器 26.0.0
  4. 点击 OK 安装所有选定的 SDK 软件包。

现在,您可以开始使用 Android 8.0 进行构建了。

更新构建配置

compileSdkVersiontargetSdkVersion 和支持库版本更新为最新可用的修订版本,例如:

android {
  compileSdkVersion 26

  defaultConfig {
    targetSdkVersion 26
  }
  ...
}

dependencies {
  compile 'com.android.support:appcompat-v7:26.0.0'
}

// REQUIRED: Google's new Maven repo is required for the latest
// support library that is compatible with Android 8.0
repositories {
    google()

    // If you're using a version of Gradle lower than 4.1, you must instead use:
    // maven {
    //     url 'https://maven.google.com'
    // }
}

从清单文件中移除广播接收器

由于 Android 8.0(API 级别 26)引入了新的广播接收器限制,因此您应移除所有为隐式广播 intent 注册的广播接收器。保留这些标记不会在构建时或运行时中断您的应用,但当应用在 Android 8.0 上运行时不会产生任何影响。

只有您的应用可以响应的广播(显式广播 intent 和专门发送到应用软件包名称的广播)在 Android 8.0 上仍以相同方式工作。

这个新增限制有一些例外情况。如需查看在以 Android 8.0 为目标平台的应用中仍然有效的隐式广播的列表,请参阅隐式广播例外

测试 Android 8.0 应用

完成上述准备工作后,您便可以构建应用,然后进一步测试,以确保应用在以 Android 8.0(API 级别 26)为目标平台时能够正常运行。这时有必要再次回顾一下核心应用质量指南测试最佳实践

如果您在构建应用时将 targetSdkVersion 设置为 26,则应该注意特定的平台变化。即便您不实现 Android 8.0 中的新功能,其中的一些变化仍可能严重影响应用的行为或令其根本无法运行。

表 2 列出了这些变化以及可获得更多信息的链接。

表 2. targetSdkVersion 设置为 26 时影响应用的关键变化。

更改 摘要 其他参考资料
隐私权 Android 8.0(API 级别 26)不支持使用 net.dns1、net.dns2、net.dns3 或 net.dns4 系统属性。 行为变更:隐私权
实行了可写且可执行的代码段 对于原生库,Android 8.0(API 级别 26)强制执行以下规则:数据不应可执行,代码不应可写入。 行为变更:原生库
ELF 标头和节验证 动态链接器会检查 ELF 标头和节标头中的更多值,如果无效值则会失败。 行为变更:原生库
通知 以 SDK 的 Android 8.0(API 级别 26)版本为目标平台的应用必须实现一个或多个通知渠道,以便向用户发布通知。 API 概览:通知
List.sort() 方法 该方法的实现不得再调用 Collections.sort(),否则应用将因堆栈溢出而引发异常。 行为变更:集合处理
Collections.sort() 方法 在列表实现中,Collections.sort() 现在会引发 ConcurrentModificationException 行为变更:集合处理

如需查看更详尽的 Android 8.0(API 级别 26)行为变更列表,请参阅 Android 8.0 行为变更

如需探索 Android 8.0(API 级别 26)中提供的新功能和 API,请参阅 Android 8.0 功能和 API