第二个 Android 11 开发者预览版现已推出,快来测试并分享您的反馈吧

测试备份和恢复

本页介绍了如何使用自动备份键值对备份功能手动触发备份和恢复操作,以确保您的应用可以正常保存和恢复数据。

备份的工作原理

本部分介绍了 Android 备份框架中的各个部分,以及它们如何与支持自动备份和键值对备份的应用交互。在应用开发阶段,由于该框架的大部分内部工作原理剥离了出来,因此您无需了解该信息。但是,在测试阶段,了解这些概念非常重要。

下图说明了在备份和恢复期间数据如何流动:backup-framework

Backup Manager Service 是一项 Android 系统服务,可以编排并启动备份和恢复操作。您可以通过 BackupManager API 访问该服务。在备份操作执行过程中,该服务会查询您的应用以获取备份数据,然后将其传递给备份传输,备份传输会将数据归档。在恢复操作执行过程中,Backup Manager Service 会从备份传输检索备份数据,然后将数据恢复到设备。

备份传输是负责存储和检索备份的 Android 组件。Android 设备可以有零个或更多个备份传输,但只能将其中一个备份传输标记为有效。由于设备制造商和服务提供商所做的自定义,可用的备份传输可能会因设备而异,但大多数支持 Google Play 的设备都搭载以下传输:

  • Google 传输(默认)- 在大部分设备上有效的备份传输,是 Google 移动服务的一部分。本文档假定用户使用的是 Google 传输。该传输会将自动备份数据存储在用户 Google 云端硬盘帐号中的私人文件夹中,将键值对备份数据存储在 Android Backup Service 中。
  • 本地传输 - 将备份数据存储在设备本地。该传输通常用于开发/调试目的,在现实场景中并不实用。

如果设备没有任何备份传输,将无法备份数据。您的应用不会受到不利影响。

注意:由于备份传输可能会因设备而异,因此 Android 无法保证使用备份时您的数据的安全性。在使用备份存储敏感数据(例如用户名和密码)时,请务必保持谨慎。

前提条件

要测试备份和恢复操作,您需要对以下工具有一定了解。

  • adb - 用于在设备或模拟器上运行命令
  • bmgr - 用于执行各种备份和恢复操作
  • logcat - 用于查看备份和恢复操作的输出。

准备设备或模拟器

请参照以下核对清单准备您的设备或模拟器,以进行备份测试:

  • 对于自动备份,请检查您使用的是否是搭载 Android 6.0(API 级别 23)或更高版本的设备或模拟器。
  • 对于键值对备份,请检查您使用的是否是搭载 Android 2.2(API 级别 8)或更高版本的设备或模拟器。
  • 检查您是否在设备或模拟器上启用了“备份和恢复”服务,以及是否已添加 Google 帐号。您可以通过以下两种方式进行检查:
    • 您可以依次转到设置 > 备份和恢复,也可以直接在屏幕顶部的搜索栏中搜索备份,具体取决于设备的版本。
    • 从 adb shell 运行 bmgr enabled

    在物理设备上,“备份和恢复”通常在初始设置向导中启用。模拟器不会运行设置向导,因此请记得在设备设置中启用备份并指定备份帐号。

  • 运行以下命令,确保 Google 备份传输可用且处于有效状态:
        adb shell bmgr list transports
        

    然后,检查控制台是否具有以下输出:

        android/com.android.internal.backup.LocalTransport
        * com.google.android.gms/.backup.BackupTransportService
        

未安装 Google Play 的物理设备和未使用 Google API 的模拟器可能不包含 Google 备份传输。本文档假定您使用的是 Google 备份传输。您可以使用其他备份传输来测试备份和恢复,但过程和输出可能会有所不同。

测试备份

要启动应用备份,请运行以下命令:

    adb shell bmgr backupnow <PACKAGE>
    

backupnow 命令适用于搭载 Android 7.0 或更高版本的设备和模拟器。该命令会运行键值对备份或自动备份,具体取决于软件包的清单声明。检查 logcat 以查看备份过程的输出。例如:

    D/BackupManagerService: fullTransportBackup()
    I/GmsBackupTransport: Attempt to do full backup on <PACKAGE>

    ---- or ----

    V/BackupManagerService: Scheduling immediate backup pass
    D/PerformBackupTask: starting key/value Backup of BackupRequest{pkg=<PACKAGE>}
    

如果 backupnow 命令不适用于您的设备,请针对自动备份或键值对备份完成以下步骤。

对于自动备份,请完成以下步骤:

  1. 运行以下命令:
        adb shell bmgr backup @pm@ && adb shell bmgr run
        
  2. 等待上一步中的命令完成运行,方法为:监控 adb logcat 是否具有以下输出:
        I/BackupManagerService: K/V backup pass finished.
        
  3. 运行以下命令以执行完整备份:
        adb shell bmgr fullbackup <PACKAGE>
        

注意:即使您的应用实现了键值对备份,fullbackup 命令也会强制其执行完整备份。系统会忽略您的应用的备份配置,当成 android:fullBackupOnly 属性设置为 true。

对于键值对备份,请按照以下步骤安排和运行备份:

  1. 如果您的应用自上次备份以来未调用 BackupManager.dataChanged(),您可以通过运行以下命令,出于测试目的对应用执行备份操作:
        adb shell bmgr backup <PACKAGE>
        
  2. 然后,您可以通过运行以下命令触发备份:
        adb shell bmgr run
        

bmgr backup 会将您的应用添加到备份管理器的队列中。 bmgr run 会启动备份操作,强制备份管理器执行其队列中的所有备份请求。

在测试键值对备份时,您必须验证是否每一项偏好设置更改都安排了备份。您可以使用以下任一方法验证是否安排了备份:

  • 运行 adb shell dumpsys backup 并检查您的应用是否列在该命令的输出中的 Pending key/value backup 下。
  • 在安排备份时记录一条消息。然后,您可以运行 adb logcat 并检查该命令的输出,以验证是否已安排备份。

测试恢复

要手动启动恢复,请使用备份令牌运行以下命令(请参阅下文,了解如何获取备份令牌):

    adb shell bmgr restore <TOKEN> <PACKAGE>
    

要查找备份令牌,请运行 adb shell dumpsys backup。令牌是跟在 Ancestral:Current: 标签之后的十六进制字符串。”ancestral“令牌是指在对设备进行初始设置(使用设备设置向导)时用于恢复设备的备份数据集。”current“令牌是指设备的当前备份数据集(设备目前将其备份数据发送到的数据集)。

然后,检查 logcat 以查看恢复过程的输出。例如:

    V/BackupManagerService: beginRestoreSession: pkg=<PACKAGE> transport=null
    V/RestoreSession: restorePackage pkg=<PACKAGE> token=368abb4465c5c683
    ...
    I/BackupManagerService: Restore complete.
    

您可以测试应用的自动恢复操作,方法是:使用 adb 或通过 Google Play 商店应用卸载并重新安装应用。

问题排查

本部分将帮助您排查一些常见问题。

超出传输配额

如果您在 logcat 中看到以下消息:

    I/PFTBT: Transport rejected backup of <PACKAGE>, skipping

    --- or ---

    I/PFTBT: Transport quota exceeded for package: <PACKAGE>
    

则说明您的应用已超出配额。请减少备份数据量,然后重试。例如,验证您是否仅将数据缓存到应用的缓存目录中。缓存目录不包含在备份中。

无法执行完整备份

如果您在 logcat 中看到以下消息:

    I/BackupManagerService: Full backup not currently possible -- key/value backup not yet run?
    

则说明完整备份操作失败,原因是设备上尚未发生任何键值对备份操作。请使用命令 bmgr run 触发键值对备份,然后重试。

等待代理超时

如果您在 logcat 中看到以下消息:

    12-05 18:59:02.033  1910  2251 D BackupManagerService:
        awaiting agent for ApplicationInfo{5c7cde0 com.your.app.package}
    12-05 18:59:12.117  1910  2251 W BackupManagerService:
        Timeout waiting for agent ApplicationInfo{5c7cde0 com.your.app.package}
    12-05 18:59:12.117  1910  2251 W BackupManagerService:
        Can't find backup agent for com.your.app.package
    

则说明您的应用启动备份所用的时间超过 10 秒。请注意日志输出中的时间戳差异。在无 ProGuard 的情况下,您的应用如果使用多 dex 文件配置,通常会发生此错误。

备份帐号未初始化

如果您在 logcat 中看到以下消息:

    01-31 14:32:45.698 17280 17292 I Backup: [GmsBackupTransport] Try to backup for an uninitialized backup account.
    01-31 14:32:45.699  1043 18255 W PFTBT: Transport failed; aborting backup: -1001
    01-31 14:32:45.699  1043 18255 I PFTBT: Full backup completed with status: -1000
    

则说明备份操作已取消,原因是备份数据集未初始化。 请使用命令 adb shell bmgr run 运行备份管理器,然后再次尝试执行备份。

应用方法未被调用

由于自动备份功能使用 Application 的基类启动应用,应用的设置方法可能不会被调用。自动备份功能也不会启动您应用的任何 Activity,因此如果您的应用在一个 Activity 中执行了设置操作,系统可能会显示错误。要了解详情,请阅读实现 BackupAgent

相反,键值对备份会使用您在应用清单文件中声明的任何 Application 子类启动您的应用。