本页介绍了如何使用自动备份和键值对备份功能手动触发备份和恢复操作,以确保您的应用可以正常保存和恢复数据。
备份的工作原理
本部分介绍了 Android 备份框架中的各个部分,以及它们如何与支持自动备份和键值对备份的应用交互。在应用开发阶段,由于该框架的大部分内部工作机制剥离了出来,因此您无需了解此信息。但是,在测试阶段,了解这些概念非常重要。
下图说明了在备份和恢复期间数据如何流动:
Backup Manager Service 是一项 Android 系统服务,可以编排并启动备份和恢复操作。您可以通过 BackupManager
API 访问该服务。在备份操作执行过程中,该服务会查询您的应用以获取备份数据,然后将其传递给备份传输,备份传输会将数据归档。在恢复操作执行过程中,Backup Manager Service 会从备份传输检索备份数据,然后将数据恢复到设备。
备份传输是负责存储和检索备份的 Android 组件。Android 设备可以有零个或更多个备份传输,但只能将其中一个备份传输标记为有效。由于设备制造商和服务提供商所做的自定义,可用的备份传输可能因设备而异,但大多数支持 Google Play 的设备都搭载以下传输:
- Google 传输(默认)- 在大部分设备上有效的备份传输,是 Google 移动服务的一部分。本文档假定用户使用的是 Google 传输。该传输会将自动备份数据存储在用户 Google 云端硬盘帐号中的私人文件夹中。将键值对备份数据存储在 Android Backup Service 中。
- 本地传输 - 将备份数据存储在设备本地。该传输通常用于开发/调试目的,在现实场景中并不实用。
如果设备没有任何备份传输,将无法备份数据。您的应用不会受到不利影响。
注意:由于备份传输可能因设备而异,因此 Android 无法保证您的数据在使用备份时的安全性。在使用备份存储用户名和密码等敏感数据时,请务必保持谨慎。
前提条件
如需测试备份和恢复操作,您需要对以下工具有一定了解。
准备设备或模拟器
请参照以下核对清单准备您的设备或模拟器,以进行备份测试:
- 对于自动备份,请检查您使用的是否是搭载 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
命令不适用于您的设备,请针对自动备份或键值对备份完成以下步骤。
对于自动备份,请完成以下步骤:
- 运行以下命令:
adb shell bmgr backup @pm@ && adb shell bmgr run
- 等待上一步中的命令完成运行,方法为:监控
adb logcat
是否具有以下输出:I/BackupManagerService: K/V backup pass finished.
- 运行以下命令以执行完整备份:
adb shell bmgr fullbackup <PACKAGE>
注意:即使您的应用实现了键值对备份,fullbackup
命令也会强制其执行完整备份。系统会忽略应用的备份配置,按照 android:fullBackupOnly
属性设置为 true 进行操作。
对于键值对备份,请按照以下步骤安排和运行备份:
- 如果您的应用自上次备份以来未调用
BackupManager.dataChanged()
,您可以通过运行以下命令,出于测试目的将您的应用包含在备份操作中:adb shell bmgr backup <PACKAGE>
- 然后,您可以通过运行以下命令触发备份:
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 的情况下,您的应用如果使用 MultiDex 配置,通常会发生此错误。
备份帐号未初始化
如果您在 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
子类启动您的应用。