测试备份和恢复

本页面介绍了如何测试应用的云备份和设备到设备 (D2D) 传输流程。在应用的每个主要版本发布时,务必对这两项功能进行测试,以确保用户可以在新设备上继续使用您的应用。虽然备份和传输类似,但在 Android 12(API 级别 31)及更高版本中,两者之间存在重要差异,其中最值得注意的是,传输的数据大小上限为 2 GB,而云备份的数据大小上限为 25 MB。

本指南介绍了如何在整个开发周期中高效地测试云备份、恢复和 D2D 传输。

备份测试的工作原理

本部分介绍 Android 备份框架中的各个部分以及它们如何与支持自动备份和键值对备份的应用交互。在应用开发阶段,框架的大部分内部工作原理都被抽象化,因此您无需了解这些信息。然而,在测试阶段,理解这些概念变得更加重要。

下图说明了云备份和恢复期间的数据流。为了进行测试,云备份和恢复可以使用同一设备。

Backup Framework Data Flow

下图说明了 D2D 传输期间的数据流

Transfer Framework Data Flow

与云备份和恢复测试不同,D2D 测试需要源设备和目标设备来进行数据的复制。

备份管理器服务是 Android 系统服务,用于协调和发起备份及恢复操作。可以通过 Backup Manager API 访问该服务。

在备份操作期间,该服务会查询您的应用获取备份数据,然后将其交给备份传输,备份传输随后将数据归档到云端。在恢复操作期间,备份管理器服务会从备份传输中检索备份数据,并将数据恢复到设备。对于 D2D 传输,备份管理器服务会查询您的应用获取备份数据,并将其直接传递给新设备上的备份管理器服务,后者将其加载到您的应用中。

备份传输是负责存储和检索应用数据的 Android 组件。一台 Android 设备可以有一个或多个备份传输,但只能将其中一个标记为活动状态。由于设备制造商和服务提供商的定制,可用的备份传输因设备而异,但大多数支持 Google Play 的设备都预装了以下传输方式:

  • GMS 传输:大多数设备上活动的云备份传输方式,是 Google Mobile Services 的一部分。此传输方式将数据存储在 Android 备份服务中。
  • D2D 传输:此传输方式用于 D2D 迁移,可将数据直接从一台设备传输到另一台设备。

工具

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

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

测试云备份

按照本部分中的步骤,可以使用单台设备执行云备份和恢复。

准备设备或模拟器进行云备份

按照以下清单准备您的设备或模拟器进行备份测试:

  1. 对于自动备份,请检查您使用的是运行 Android 6.0(API 级别 23)或更高版本的设备或模拟器。
  2. 对于键值对备份,请检查您使用的是运行 Android 2.2(API 级别 8)或更高版本的设备或模拟器。
  3. 您必须有互联网连接才能测试云备份。
  4. 使用 Google 账号登录设备,并在 Settings -> Google -> Backup(设置 -> Google -> 备份)中将其设置为备份账号。

要测试云备份,请触发云备份,然后卸载并重新安装应用。为了使这些步骤可重复,您可以使用以下脚本 test_cloud_backup.sh,该脚本会备份您的应用,在本地下载 APK,卸载并重新安装 APK。

#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell bmgr transport com.android.localtransport/.LocalTransport | grep -q "Selected transport" || (echo "Error: error selecting local transport"; exit 1)
adb shell settings put secure backup_local_transport_parameters 'is_encrypted=true'
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

测试步骤

  1. 打开您的应用,登录,并修改所有设置。
  2. 运行脚本,传入您的软件包名称,例如 test_cloud_backup.sh com.example.myapp
  3. 重新打开应用,验证其是否正常工作且所有数据都已保留。

您不希望用户需要重新登录,并且他们的所有设置、进度和应用数据都必须与之前一样。如果您的测试结果不符合这些条件,请确保您已正确配置备份,没有遗漏关键数据,并且您也正在处理重建从备份中排除的任何缓存数据。对于每个测试迭代,重复步骤 1-3。

测试 D2D 传输

测试 D2D 传输最全面的方法是将您整个手机的内容传输到一台新的、恢复出厂设置的设备,并验证其是否正常工作。但是,如果您需要多次重复此过程,这可能会不方便且耗时。这些步骤将向您展示如何在单台设备上模拟传输,而无需重复对设备执行恢复出厂设置。

准备您的设备进行 D2D 测试

要在单台设备上测试 D2D 传输,请按如下方式准备设备:

  1. 您的设备必须运行 Android 12(API 级别 31)或更高版本。
  2. 要测试最新版本的 D2D,请在您的应用中将目标平台设置为 Android 12(API 级别 31)或更高版本。
  3. 创建以下脚本 test_d2d.sh,以支持重复测试:
#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell settings put secure backup_enable_d2d_test_mode 1
adb shell bmgr transport com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr list transports | grep -q -F "  * com.google.android.gms/.backup.migrate.service.D2dTransport" || (echo "Failed to select and initialize backup transport"; exit 1)
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell settings put secure backup_enable_d2d_test_mode 0
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

测试步骤

  1. 在设备上安装您要测试的应用。
  2. 打开您的应用,登录,并修改应用的设置。
  3. 在您的设备上运行脚本,传入您的软件包名称,例如 test_d2d.sh com.example.myapp
  4. 脚本完成后,在设备上打开应用,验证其是否正常工作且所有数据都已保留。

您不希望用户需要重新登录,并且他们的所有设置、进度和应用数据都必须与运行脚本之前一样。如果您的测试结果不符合这些条件,请确保您已正确配置传输,没有遗漏关键数据,并且您也正在处理重建从传输中排除的任何缓存数据。对于每个测试迭代,重复步骤 2-4。

备份和恢复问题排查

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

超出传输配额

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 中的以下消息表示您的应用启动备份所需时间超过 10 秒:

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

请注意日志输出中的时间戳差异。此错误通常发生在您的应用使用 multidex 配置但未使用 ProGuard 的情况下。

未初始化的备份账号

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

相比之下,键值对备份会使用您在应用 manifest 文件中声明的任何 Application 子类启动您的应用。

没有要备份的数据

Logcat 中的以下消息表示您的应用没有要备份的数据:

I Backup  : [FullBackupSession] Package com.your.app.package doesn't have any backup data.

--- or ---

I Backup  : [D2dTransport] Package com.your.app.package doesn't have any backup data.

如果您实现了您自己的 BackupAgent,这可能意味着您尚未向备份添加任何数据或文件。