兼容性框架工具

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 的名为“已启用,目标 SDK 版本 >= 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
指示哪个应用受更改影响。
状态

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

状态可以是以下值之一

状态 含义
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 15(API 级别 35),您可以先将应用安装在运行 Android 15 的设备上,并使用您常用的测试工作流程测试应用。如果您的应用遇到问题,您可以禁用导致问题的更改,以便您可以继续测试其他问题。

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

您还应优先测试这些更改,因为您在使用 Android 的公共发布版本时无法禁用这些更改。理想情况下,您应在每个 Android 版本处于预览阶段时对这些更改进行测试。

targetSDKVersion 控制的更改

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

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

何时启用更改

受特定 targetSDKVersion 控制的更改在应用以低于受控版本的 SDK 版本为目标时默认禁用。通常,当您准备以新的 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 版构建 无法切换 可以切换 可以切换
公共用户构建 无法切换 可以切换 无法切换