Android 11 引入了一些新的开发者工具,供您用于测试和调试自己的应用,检查其是否兼容更高版本的 Android 平台中的行为变更。这些工具属于兼容性框架的一部分,可让应用开发者使用开发者选项或 adb 单独启用或停用各项重大变更。您可以利用这种灵活性做好准备,以便以最新稳定版 API 为目标平台和使用下一个 Android 版本的预览版测试应用。
当您使用兼容性框架工具时,Android 平台会自动调整其内部逻辑,因此您无需更改 targetSDKVersion
或重新编译应用即可执行基本测试。由于各项变更可单独启用/停用,因此您可以一次隔离、测试和调试一项行为变更,或者停用一项在您需要先测试其他变更时会导致出现问题的变更。
如何识别已启用的变更
启用行为变更可能会影响您的应用访问受该变更影响的平台 API 的方式。您可以使用开发者选项、logcat 或 adb 命令查看已启用的行为变更。
使用开发者选项识别已启用的变更
您可以在设备的开发者选项中查看已启用的变更,并且可以开启/关闭这些变更。如需访问这些选项,请按以下步骤操作:
- 如果开发者选项尚未启用,请启用开发者选项。
- 打开设备的“设置”应用,然后依次导航到系统 > 高级 > 开发者选项 > 应用兼容性变更。
从列表中选择您的应用。
每项行为变更通常属于以下两种类别之一:
会影响在相应 Android 版本上运行的所有应用的变更,无论应用的
targetSdkVersion
为何。默认情况下,这些变更在兼容性框架中处于启用状态,并且会在界面的默认启用的应用兼容性变更部分中列出。
只会影响以特定 Android 版本为目标平台的应用的变更。 由于这些变更只会影响以特定 Android 版本为目标平台的应用,因此它们也称为受
targetSDKVersion
控制的变更。如果您的应用以高于所列 API 版本的 Android 版本为目标平台,默认情况下,这些变更会在兼容性框架中处于启用状态。例如,Android 13(API 级别 33)中受
targetSDKVersion
控制的行为变更会在界面的已为 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
- 指示受该变更影响的应用。
- 状态
指示该变更是否正在影响应用。
状态可以是以下值之一:
状态 含义 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
控制的变更在默认情况下可以处于启用状态,也可以处于停用状态,因此该软件包列表可以同时包含true
或false
实例,具体取决于每个应用的targetSDKVersion
。例如:packageOverrides={com.my.package=true, com.another.package=false}
详细了解具体变更
兼容性框架中的完整行为变更列表包含在每个 Android 版本的文档中。如需了解详情,请访问以下链接(具体取决于您使用哪个 Android 版本测试应用):
- Android 15(API 级别 35)
- Android 14(API 级别 34)
- Android 13(API 级别 33)
- Android 12(API 级别 31 和 32)
- Android 11(API 级别 30)
何时切换变更的启用/停用状态
兼容性框架的主要目的在于,在您使用更高版本的 Android 测试应用时,为您提供可控性和灵活性。此部分介绍了一些策略,可在测试和调试应用时用来确定何时启用或停用变更。
何时停用变更
确定何时停用变更通常取决于相应变更是否受 targetSDKVersion
控制。
- 对所有应用启用变更
对于特定的平台版本,影响所有应用(无论应用的
targetSDKVersion
为何)的变更在默认情况下处于启用状态,因此您可以通过在该平台版本上运行应用来了解其是否受到影响。例如,如果您准备以 Android 15(API 级别 35)为目标平台,则可以先在搭载 Android 15 的设备上安装您的应用,并使用典型的测试工作流测试应用。如果您的应用遇到问题,您可以停用导致出现问题的变更,以便继续测试是否存在其他问题。
由于这些变更会影响所有应用(无论
targetSDKVersion
为何),因此您通常应该先针对这些变更测试并更新您的应用,然后再针对受targetSDKVersion
控制的变更测试和更新您的应用。这有助于确保用户在将其设备更新到新的平台版本时,应用体验不会变差。您也应该优先测试这些变更,因为在使用 Android 的公开发布 build 时,您无法停用这些变更。理想情况下,您应该在每个 Android 版本处于预览版状态时针对这些变更执行测试。
- 受
targetSDKVersion
控制的变更 如果您的应用以特定的
targetSDKVersion
为目标平台,则受该版本控制的任何变更都会在默认情况下处于启用状态。因此,当您将应用的targetSDKVersion
切换到新版本时,您的应用将开始同时受到许多新变更的影响。由于应用可能会受到多项变更的影响,因此在测试和调试应用时,您可能需要逐项停用其中的部分变更。
何时启用变更
对于受特定 targetSDKVersion
控制的变更,当应用的目标 SDK 版本低于该控制版本时,这些变更在默认情况下会处于停用状态。通常,当您准备以新的 targetSdkVersion
为目标平台时,您将获得一个行为变更列表,您需要针对这些变更测试和调试应用。
例如,您可能需要针对下一 targetSdkVersion
中的一系列平台变更测试您的应用。您可以使用开发者选项或 adb 命令逐个启用和测试受 targetSDKVersion 控制的变更,而不是更改应用清单并一次性选择启用所有变更。这项附加控制可以帮助您单独测试各项变更,避免同时调试和更新应用的多个部分。
启用变更后,您可以使用典型的测试工作流测试和调试应用。如果您遇到问题,请查看日志以帮助确定问题的原因。如果不确定该问题是否由已启用的某项平台变更导致,请尝试停用该变更,然后重新测试应用的相应区域。
启用或停用变更
兼容性框架支持您使用开发者选项或 adb 命令启用或停用各项变更。由于启用或停用变更可能会导致应用崩溃或停用重要的安全变更,因此对于何时可以切换变更的启用/停用状态有一些限制。
使用开发者选项启用或停用变更
您可以使用开发者选项启用或停用变更。如需找到开发者选项,请按以下步骤操作:
- 如果开发者选项尚未启用,请启用开发者选项。
- 打开设备的“设置”应用,导航到系统 > 高级 > 开发者选项 > 应用兼容性变更。
- 从列表中选择您的应用。
在变更列表中,找到想要开启或关闭的变更,然后点按相应的开关。
使用 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 版本低于该版本阈值,这些变更在默认情况下将处于停用状态。当您启用或停用某项变更时,会替换其默认状态。
为了避免兼容性框架遭到恶意使用,对于何时可以切换变更的启用/停用状态有一些限制。是否可以切换变更的状态取决于变更的类型、应用的可调试性,以及设备上运行的 build 类型。下表介绍了不同类型的变更的状态切换限制:
build 类型 | 不可调试的应用 | 可调试的应用 | |
---|---|---|---|
所有变更 | 受 targetSDKVersion 控制的变更 | 所有其他变更 | |
开发者预览版或 Beta 版 build | 无法切换 | 可以切换 | 可以切换 |
公开用户 build | 无法切换 | 可以切换 | 无法切换 |