Google 致力于为黑人社区推动种族平等。查看具体举措

通过自动备份功能备份用户数据

应用自动备份功能会自动备份面向并在 Android 6.0(API 级别 23)或更高版本的系统中运行的应用中的用户数据。Android 通过将应用数据上传到用户的 Google 云端硬盘来保留这些数据;在 Google 云端硬盘中,这些数据受到用户的 Google 帐号凭据的保护。数据量上限为应用的每个用户 25MB,并且存储备份数据是免费的。应用可以自定义备份流程,也可以通过停用备份选择将其停用。

要简要了解 Android 备份选项以及有关您应该备份和恢复哪些数据的指南,请参阅数据备份概览

要练习如何设置自动备份功能,您还可以尝试 Android 自动备份 Codelab

备份的文件

默认情况下,自动备份功能会备份系统分配给应用的大多数目录中的文件:

自动备份功能会排除 getCacheDir()getCodeCacheDir()getNoBackupFilesDir() 返回的目录中的文件。这些位置所保存的文件只是临时需要,或故意从备份操作中排除。

您可以将应用配置为包含和排除特定文件。如需了解详情,请参阅包含和排除文件部分。

注意:Android 不会将组件配置视为用户数据。如果应用在运行时启用或停用其清单中的特定组件,请注意,AutoBackup 不会保存和恢复相应配置。要保留配置状态,请将其保存到共享偏好设置中,并在恢复时恢复共享偏好设置。如果您想让应用保存其状态,请将状态信息保存到共享偏好设置中,并在恢复时恢复共享偏好设置。

备份位置

备份数据存储在用户的 Google 云端硬盘帐号的私人文件夹中,每个应用的数据量上限为 25MB。保存的数据不计入用户的个人 Google 云端硬盘配额。系统仅存储最新备份。进行备份时,系统会删除先前的备份(如果存在)。用户或设备上的其他应用无法读取备份数据。

用户可以在 Google 云端硬盘 Android 应用中查看已备份应用的列表。在 Android 设备中,用户可以在 Google 云端硬盘应用的抽屉式导航栏中找到此列表,只需依次转到设置 > 备份和重置 > 应用数据即可。

每个设备设置生命周期中的备份存储在不同的数据集中,具体如以下示例所示:

  • 如果用户拥有两个设备,则每个设备都存在备份数据集。
  • 如果用户将设备恢复出厂设置,然后使用相同的帐号设置此设备,则备份会存储在新的数据集中。过时数据集会在一段闲置时间后自动删除。

备份计划

满足以下所有条件时,备份会自动进行:

  • 用户已在设备上启用了备份功能。在 Android 9 中,此设置位于设置 > 系统 > 备份中。
  • 自上次备份以来已经过了至少 24 小时。
  • 设备处于闲置状态。
  • 设备已连接到 WLAN 网络(如果设备用户未选择启用移动数据备份)。

在实践中,这些情况大概每天晚上都会发生,但设备可能永远不会进行备份(例如,如果设备一直未连接到网络)。为了节省网络带宽,仅在应用数据发生更改时才会进行上传。

在自动备份期间,系统会关闭应用以确保其不再向文件系统写入数据。默认情况下,备份系统会忽略在前台运行的应用,因为用户会注意到其应用被关闭的情况。您可以通过将 backupInForeground 属性设为 true 来替换默认行为。

为了简化测试,Android 提供了可让您手动启动应用备份的工具。如需了解详情,请参阅测试备份和恢复

恢复计划

每当通过 Play 商店安装应用、在设备设置过程中安装应用(系统安装之前安装的应用时)或通过运行 adb install 安装应用时,数据都会恢复。恢复操作会在 APK 安装完成后,应用可供用户启动之前的这段时间内发生。

在初始设备设置向导运行期间,系统会向用户显示可用的备份数据集列表,并询问用户从哪个数据集恢复数据。选择哪个备份数据集,哪个数据集就会成为设备的原始数据集。设备可以从自己的备份或原始数据集进行恢复。如果这两个来源的备份都可用,则设备会优先考虑自己的备份。如果用户未完成设备设置向导,则设备只能从自己的备份进行恢复。

为了简化测试,Android 提供了可让您手动启动应用恢复的工具。如需了解详情,请参阅测试备份和恢复

启用和停用备份

面向 Android 6.0(API 级别 23)或更高版本的应用会自动参与自动备份。在应用清单文件中,设置布尔值 android:allowBackup 即可启用或停用备份。默认值为 true,但为了明确您的意图,我们建议您在清单中明确设置此属性,如下所示:

<manifest ... >
        ...
        <application android:allowBackup="true" ... >
            ...
        </application>
    </manifest>
    

您可以通过将 android:allowBackup 设置为 false 来停用备份。如果应用可以通过其他机制重新创建其状态,或应用会处理 Android 不应备份的敏感信息,则可能需要执行此操作。

包含和排除文件

默认情况下,系统会备份几乎所有应用数据。如需了解详情,请参阅备份的文件。本部分介绍了如何定义自定义 XML 规则以控制备份的内容。

  1. AndroidManifest.xml 中,将 android:fullBackupContent 属性添加到 <application> 元素中。此属性指向包含备份规则的 XML 文件。例如:
        <application ...
            android:fullBackupContent="@xml/my_backup_rules">
        </application>
        
  2. res/xml/ 目录中创建名为 my_backup_rules.xml 的 XML 文件。在此文件中,使用 <include><exclude> 元素添加规则。 以下示例会备份除 device.xml 之外的所有共享偏好设置:
        <?xml version="1.0" encoding="utf-8"?>
        <full-backup-content>
            <include domain="sharedpref" path="."/>
            <exclude domain="sharedpref" path="device.xml"/>
        </full-backup-content>
        

XML 配置语法

配置文件的 XML 语法如下所示:

    <full-backup-content>
        <include domain=["file" | "database" | "sharedpref" | "external" | "root"]
        path="string"
        requiredFlags=["clientSideEncryption" | "deviceToDeviceTransfer"] />
        <exclude domain=["file" | "database" | "sharedpref" | "external" | "root"]
        path="string" />
    </full-backup-content>
    

您可以在 <full-backup-content> 标记中定义 <include><exclude> 元素:

  • <include> - 指定要备份的文件或文件夹。默认情况下,自动备份会涵盖应用的几乎所有文件。如果您指定 <include> 元素,则系统不会再涵盖任何默认文件,并仅备份指定的文件。要涵盖多个文件,请使用多个 <include> 元素。

    注意:系统始终会排除 getCacheDir()getCodeCacheDir()getNoBackupFilesDir() 返回的目录中的文件,即使您尝试包含这些文件也是如此。

  • <exclude> - 指定在备份期间要排除的文件或文件夹。以下是通常会从备份中排除的一些文件:
    • 包含由服务器生成或由设备生成的设备特定标识符的文件。例如,每当用户在新设备上安装您的应用时,Google 云消息传递 (GCM) 都需要生成注册令牌。如果旧的注册令牌恢复了,则应用可能会出现意外行为。
    • 帐号凭据或其他敏感信息。考虑让用户在第一次启动恢复的应用时重新进行身份验证,而不是允许在备份中存储此类信息。
    • 与应用调试相关的文件。
    • 导致应用超过 25MB 的备份配额的大型文件。

注意:如果您的配置文件同时指定了这两个元素,则备份包含 <include> 元素指定的所有资源减去 <exclude> 元素指定的资源。换句话说,<exclude> 优先。

每个元素都必须包含以下两个属性:

  • domain - 指定资源的位置。此属性的有效值包括以下各项:
  • 注意:您无法备份这些位置之外的文件。

  • path:指定备份要包含或排除的文件或文件夹。注意:
    • 此属性不支持通配符或正则表达式语法。
    • 您可以使用 . 引用当前目录,不过,出于安全考虑,您无法引用父目录 ..
    • 如果您指定一个目录,则该规则适用于此目录及递归子目录中的所有文件。

include 元素还可以包含 requiredFlags 属性,介绍如何定义备份条件要求的部分对此有详细论述。

定义备份所需的设备条件

如果您的应用在设备上保存敏感信息,则您可以指定用户备份在哪些条件下会包含您的应用数据。在 Android 9(API 级别 28)或更高版本中,您可以添加以下条件:

如果您已将开发设备升级到 Android 9,则需要在升级后停用数据备份功能,然后再重新启用。这是因为只有当在“设置”或“设置向导”中通知用户后,Android 才会使用客户端密钥加密备份。

要声明包含条件,请将 requireFlags 属性设置为所需的值或备份规则集内的 <include> 元素中的值。

my_backup_rules.xml

    <?xml version="1.0" encoding="utf-8"?>
    <full-backup-content>
        <!-- App data isn't included in user's backup
             unless client-side encryption is enabled. -->
        <include domain="file" path="."
                 requireFlags="clientSideEncryption" />
    <full-backup-content>
    

如果您的应用实现了键值对备份系统,或您自己实现了 BackupAgent,则您还可以将这些条件要求应用于您的备份逻辑,方法是在 BackupDataOutput 对象的传输标记集与自定义备份代理的 FLAG_CLIENT_SIDE_ENCRYPTION_ENABLEDFLAG_DEVICE_TO_DEVICE_TRANSFER 标记之间执行按位比较。

以下代码段显示了此方法的示例用法:

Kotlin

    class MyCustomBackupAgent : BackupAgent() {
        override fun onBackup(oldState: ParcelFileDescriptor?,
                data: BackupDataOutput?, newState: ParcelFileDescriptor?) {
            if (data != null) {
                if ((data.transportFlags and
                        FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
                    // Client-side backup encryption is enabled.
                }

                if ((data.transportFlags and FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
                    // Local device-to-device transfer is enabled.
                }
            }
        }

        // Implementation of onRestore() here.
    }
    

Java

    public class MyCustomBackupAgent extends BackupAgent {
        @Override
        public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
                ParcelFileDescriptor newState) throws IOException {
            if ((data.getTransportFlags() &
                    FLAG_CLIENT_SIDE_ENCRYPTION_ENABLED) != 0) {
                // Client-side backup encryption is enabled.
            }

            if ((data.getTransportFlags() &
                    FLAG_DEVICE_TO_DEVICE_TRANSFER) != 0) {
                // Local device-to-device transfer is enabled.
            }
        }

        // Implementation of onRestore() here.
    }
    

实现 BackupAgent

实现自动备份的应用不需要实现 BackupAgent。不过,您可以根据需要实现自定义 BackupAgent。通常,这样做有两个原因:

  • 您希望接收备份事件(例如 onRestoreFinished()onQuotaExceeded(long, long))的通知。即使应用未运行,这些回调方法也会执行。
  • 您无法使用 XML 规则轻松地表达要备份的文件集。在类似这样的极少数情况下,您可以实现一个替换 onFullBackup(FullBackupDataOutput) 的 BackupAgent 来存储您想要的内容。要保留系统的默认实现,请使用 super.onFullBackup() 在父类上调用相应的方法。

如果您实现了 BackupAgent,则在默认情况下,系统会要求您的应用执行键值对备份和恢复操作。要改用基于文件的自动备份功能,请在应用清单中将 android:fullBackupOnly 属性设为 true

在自动备份和恢复操作执行过程中,系统会以受限模式启动应用,以防止应用访问可能导致冲突的文件,并让应用能够在其 BackupAgent 中执行回调方法。在此受限模式下,应用的主 Activity 不会自动启动,其内容提供程序不会初始化,并且基类 Application(而不是应用的清单中声明的任何子类)会实例化。

注意:为了避免错误,请确保在受限模式下执行的应用部分(主要是 BackupAgent)不会访问同一应用中的内容提供程序,或试图转换 Application 对象的类型。如果无法避免这些模式,请考虑实现键值对备份或彻底停用备份。

您的 BackupAgent 必须实现抽象方法 onBackup()onRestore(),以用于键值对备份。但是,如果您不想执行键值对备份,则可以将这些方法的实现留空。

如需了解详情,请参阅扩展 BackupAgent

其他资源

如需详细了解自动备份,请参阅以下资源。

Codelab