兼容性框架工具

Android 11 引入了新的开发者工具,用于针对更新版本的 Android 平台的行为更改测试和调试您的应用。这些工具是兼容性框架的一部分,允许应用开发者使用开发者选项或 ADB分别启用和停用重大更改。当您准备定位最新的稳定 API 版本以及使用下一个 Android 版本的预览版测试您的应用时,可以使用此灵活性。

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

如何识别已启用的更改

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

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

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

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

  1. 如果尚未启用开发者选项,请启用它们
  2. 打开设备的“设置”应用,然后导航到系统 > 高级 > 开发者选项 > 应用兼容性更改
  3. 从列表中选择您的应用。

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

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

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

  • 仅影响针对特定 Android 版本的应用的更改。由于这些更改仅影响针对特定 Android 版本的应用,因此它们也称为由targetSDKVersion控制的更改。

    如果您的应用的目标版本高于列出的 API 版本,则这些更改在兼容性框架中默认启用。例如,由 Android 13(API 级别 33)中的targetSDKVersion控制的行为更改将在 UI 中名为为 targetSdkVersion >=33 启用的部分中列出。在某些较低版本的 Android 中,此部分的标题为“SDK API_LEVEL 后启用”。

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

使用 logcat 识别已启用的更改

对于每个行为更改,在应用进程中第一次调用受影响的 API 时,系统会输出类似这样的 logcat 消息

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

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

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

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

状态可以是以下值之一

状态 含义
已启用 已启用更改,如果应用使用已更改的 API,则会影响应用的行为。
已停用

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

注意:如果由于应用的targetSDKVersion低于所需阈值而停用此更改,则当应用将其targetSDKVersion提高到目标更高版本时,此更改将默认启用。

已记录 更改正在通过兼容性框架记录,但无法启用或停用。虽然此更改无法切换,但它仍可能影响您的应用行为。有关更多信息,请参阅该 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 15(API 级别 35),您可以首先将应用安装在运行 Android 15 的设备上,并使用典型的测试工作流程测试您的应用。如果您的应用遇到问题,您可以禁用导致问题的更改,以便您可以继续测试其他问题。

由于这些更改可能会影响所有应用,而不管targetSDKVersion如何,因此您通常应该在测试和更新受targetSDKVersion限制的更改之前测试和更新这些更改。这有助于确保用户在将设备更新到新的平台版本时不会有糟糕的应用体验。

您还应该优先测试这些更改,因为在使用 Android 的公开发布版本时,您无法禁用这些更改。理想情况下,您应该**在预览版期间**针对每个 Android 版本测试这些更改。

targetSDKVersion限制的更改

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

由于您的应用可能会受到这些更改中的多个更改的影响,因此您可能需要在测试和调试应用时单独禁用其中一些更改。

何时启用更改

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

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

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

启用或禁用更改

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

使用开发者选项切换更改

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

  1. 如果尚未启用开发者选项,请启用它们
  2. 打开设备的“设置”应用,然后导航到系统 > 高级 > 开发者选项 > 应用兼容性更改
  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 版本 无法切换 可以切换 可以切换
公开用户版本 无法切换 可以切换 无法切换