兼容性框架工具

Android 11 引入了新的开发者工具,用于根据新版本 Android 平台中的行为更改测试和调试您的应用。这些工具是兼容性框架的一部分,它允许应用开发者使用开发者选项或 ADB 单独开启和关闭破坏性更改。在您准备以最新稳定 API 版本为目标以及使用下一个 Android 版本的预览版测试您的应用时,请利用这种灵活性。

当您使用兼容性框架工具时,Android 平台会自动调整其内部逻辑,因此您无需更改targetSDKVersion 或重新编译您的应用即可执行基本测试。由于更改可以单独切换,因此您可以一次隔离、测试和调试一个行为更改,或者如果需要先测试其他内容,则禁用导致问题的单个更改。

如何识别哪些更改已启用

当行为更改启用时,它可能会影响您的应用访问受该更改影响的平台 API 的方式。您可以使用开发者选项、logcat 或 ADB 命令检查哪些行为更改已启用。

使用开发者选项识别已启用的更改

图 1. 开发者选项中的“应用兼容性更改”屏幕。

您可以在设备的开发者选项中查看哪些更改已启用并开启或关闭这些更改。要访问这些选项,请按照以下步骤操作:

  1. 如果开发者选项尚未启用,请启用它们
  2. 打开设备的“设置”应用,然后导航到 System > Advanced > Developer options > App Compatibility Changes
  3. 从列表中选择您的应用。

每个行为更改通常属于以下两个类别之一:

  • 影响在特定 Android 版本上运行的所有应用的更改,无论应用的 targetSdkVersion 如何。

    这些更改在兼容性框架中默认启用,并在 UI 的 Default Enabled Changes(默认启用更改)部分中列出。

  • 仅影响以特定 Android 版本为目标的应用的更改。由于这些更改仅影响以特定 Android 版本为目标的应用,因此它们也被称为受 targetSDKVersion 限制的更改。

    如果您的应用以高于所列 API 版本的版本为目标,则这些更改在兼容性框架中默认启用。例如,Android 13 (API level 33) 中受 targetSDKVersion 限制的行为更改将在 UI 中以标题为 Enabled for targetSdkVersion >=33 的部分列出。在某些较低版本的 Android 上,此部分的标题为 "Enabled After SDK API_LEVEL"。

您还会注意到图 1 中有一个名为 Default Disabled Changes(默认禁用更改)的部分。属于此部分的更改可以用于多种目的。在启用这些更改之前,请阅读该 Android 版本的兼容性框架列表中的更改说明。

使用 logcat 识别已启用的更改

对于每个行为更改,在您的应用进程中首次调用受影响的 API 时,系统会输出一条类似以下内容的 logcat 消息:

D CompatibilityChangeReporter: Compat change id reported: 194833441; UID 10265; state: ENABLED

每条 logcat 消息都包含以下信息:

更改 ID
指示哪个更改正在影响应用。此值映射到“应用兼容性更改”屏幕(参见图 1)上列出的行为更改之一。在此示例中,194833441 映射到 NOTIFICATION_PERM_CHANGE_ID
UID
指示哪个应用受到更改的影响。
状态

指示更改是否正在影响应用。

状态可以是以下值之一:

状态 含义
ENABLED 更改已启用,如果应用使用已更改的 API,将影响应用的表现。
DISABLED

更改已禁用,不会影响应用。

注意:如果此更改因应用的 targetSDKVersion 低于所需阈值而禁用,则当应用将其 targetSDKVersion 增加到更高版本时,该更改将默认启用。

LOGGED 更改通过兼容性框架记录,但无法开启或关闭。尽管此更改无法切换,但它可能仍会影响您的应用的行为。有关更多信息,请参阅该 Android 版本的兼容性框架列表中该更改的说明。在许多情况下,这些类型的更改是实验性的,可以忽略。

使用 ADB 识别已启用的更改

运行以下 ADB 命令以查看整个设备上所有更改(包括已启用和已禁用)的完整集合:

adb shell dumpsys platform_compat

输出列出了每个更改的以下信息:

更改 ID
此行为更改的唯一标识符。例如,194833441
名称
此行为更改的名称。例如,NOTIFICATION_PERM_CHANGE_ID
targetSDKVersion 标准

此更改受哪个 targetSDKVersion 限制(如果有)。

例如,如果此更改仅对以 SDK 版本 33 或更高版本为目标的应用启用,则输出为 enableAfterTargetSdk=32。如果更改不受 targetSDKVersion 限制,则输出为 enableAfterTargetSdk=0

软件包覆盖

更改的默认状态(启用或禁用)已被覆盖的每个软件包的名称。

例如,如果此更改默认启用,则如果您使用开发者选项或 ADB 关闭了该更改,则会列出您的应用软件包名称。在这种情况下,输出将是:

packageOverrides={com.my.package=false}

targetSDKVersion 限制的更改可以默认启用或禁用,因此软件包列表可以包含 truefalse 的实例,具体取决于每个应用的 targetSDKVersion。例如:

packageOverrides={com.my.package=true, com.another.package=false}

了解有关特定更改的更多信息

兼容性框架中行为更改的完整列表作为每个 Android 版本文档的一部分包含在内。有关更多信息,请参阅以下链接,具体取决于您正在测试应用所针对的 Android 版本:

何时切换更改

兼容性框架的主要目的是在您使用新版本 Android 测试应用时提供控制和灵活性。本节介绍了一些可用于确定在测试和调试应用时何时开启或关闭更改的策略。

何时关闭更改

决定何时关闭更改通常取决于更改是否受 targetSDKVersion 限制。

针对所有应用启用的更改

影响所有应用的更改默认针对特定平台版本启用,无论您的应用的 targetSDKVersion 如何,因此您可以通过在该平台版本上运行您的应用来查看您的应用是否受到影响。

例如,如果您准备以 Android 16 (API level 36) 为目标,您可以首先在运行 Android 16 的设备上安装您的应用,并使用您典型的测试工作流程测试您的应用。如果您的应用遇到问题,您可以禁用导致问题的更改,以便继续测试其他问题。

由于这些更改无论 targetSDKVersion 如何都可能影响所有应用,因此您通常应在受 targetSDKVersion 限制的更改之前测试并更新您的应用以适应这些更改。这有助于确保您的用户在将其设备更新到新平台版本时不会遇到应用体验降级的情况。

您还应该优先测试这些更改,因为您在使用 Android 的公开版本构建时无法关闭这些更改。理想情况下,您应该在 该版本的预览期内对每个 Android 版本进行这些更改的测试。

targetSDKVersion 限制的更改

如果您的应用以特定的 targetSDKVersion 为目标,则受该版本限制的任何更改都将默认启用。因此,当您将应用的 targetSDKVersion 切换到新版本时,您的应用将同时受到许多新更改的影响。

由于您的应用可能受不止一个此类更改的影响,因此在测试和调试应用时,您可能需要单独关闭其中一些更改。

何时开启更改

当应用以低于受限制版本的 SDK 版本为目标时,受特定 targetSDKVersion 限制的更改默认是禁用的。通常,当您准备以新的 targetSdkVersion 为目标时,您将有一个需要测试和调试应用的的行为更改列表。

例如,您可能正在根据下一个 targetSdkVersion 中的一系列平台更改来测试您的应用。使用开发者选项或 ADB 命令,您可以逐一启用和测试每个受限更改,而不是同时更改您的应用清单并选择所有更改。这种额外的控制可以帮助您隔离测试更改,并避免一次调试和更新应用中的多个部分。

启用更改后,您可以使用典型的测试工作流程测试和调试您的应用。如果您遇到问题,请检查日志以帮助确定问题的原因。如果不清楚问题是否是由已启用的平台更改引起的,请尝试禁用该更改,然后重新测试应用的该区域。

开启或关闭更改

兼容性框架允许您使用开发者选项或 ADB 命令开启或关闭每个更改。由于开启或关闭更改可能导致您的应用崩溃或禁用重要的安全更改,因此在何时可以开启或关闭更改方面存在一些限制。

使用开发者选项切换更改

使用开发者选项开启或关闭更改。要找到开发者选项,请按照以下步骤操作:

  1. 如果开发者选项尚未启用,请启用它们
  2. 打开设备的“设置”应用,然后导航到 System > Advanced > Developer options > App Compatibility Changes
  3. 从列表中选择您的应用。
  4. 从更改列表中,找到您要开启或关闭的更改,然后点击开关。

    List of changes that can be toggled on or off

使用 ADB 切换更改

要使用 ADB 开启或关闭更改,请运行以下命令之一:

adb shell am compat enable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME
adb shell am compat disable (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

传递 CHANGE_ID(例如,194833441)或 CHANGE_NAME(例如,NOTIFICATION_PERM_CHANGE_ID)以及您的应用的 PACKAGE_NAME

您还可以使用以下命令将更改重置为其默认状态,删除您使用 ADB 或开发者选项设置的任何覆盖:

adb shell am compat reset (CHANGE_ID|CHANGE_NAME) PACKAGE_NAME

切换更改的限制

默认情况下,每个行为更改都是启用或禁用的。影响所有应用的更改默认启用。其他更改受 targetSdkVersion 限制。当应用以相应 SDK 版本或更高版本为目标时,这些更改默认启用;当应用以低于受限制版本的 SDK 版本为目标时,这些更改默认禁用。当您开启或关闭更改时,您将覆盖其默认状态。

为了防止兼容性框架被恶意使用,在何时可以切换更改方面存在一些限制。您是否可以切换更改取决于更改的类型、您的应用是否可调试以及设备上运行的构建类型。下表描述了何时可以切换不同类型的更改:

构建类型 不可调试应用 可调试应用
所有更改 受 targetSDKVersion 限制的更改 所有其他更改
开发者预览版或 Beta 版构建 无法切换 可以切换 可以切换
公共用户构建 无法切换 可以切换 无法切换