三、应用的自动备份

你有没有花时间在手机上设置一个应用,用了一段时间,倾注了大量的内容,却因为一个闪失换了手机,就为了发现自己的数据和设置都飘了?

安卓棉花糖的一个关键特性是,它支持用户应用的全自动数据备份和恢复。这改善了用户体验,使整体参与更有趣,并缩短了多个设备的登机时间。就像我们在前几章讨论的,快乐的用户会带来快乐的开发者。

您可以卸下设置新设备的负担;不管是增加的设备还是替换的设备。用户最终将获得相同的应用配置和数据,从而使工作变得更加与设备无关。要在您的应用上启用该功能,您必须将安卓棉花糖软件开发工具包的版本 23 作为目标;默认情况下不需要额外的代码,即使您可以配置该功能并允许在需要时进行特定的行为。当用户更改或升级设备时,数据会自动恢复。

**在本章中,我们将了解该功能的工作原理,并配置要备份的信息。我们将涵盖以下主题:

  • 概述
  • 数据备份配置
  • 备份配置测试
  • 重要字节

概述

自动备份功能是通过将应用中创建的数据上传到用户的谷歌驱动账户,并保持加密来创建的。这不会影响用户的驱动器配额或您的配额。每个应用每个用户只能备份 25 MB,一旦达到这个数量,您的应用将停止备份。还有,注意是完全免费

备份以 24 小时为周期完成,仅在夜间进行,并且是自动完成的,通常是在设备空闲、充电并连接到无线网络时。这些条件是为了电池效率、数据充电,当然,也是为了将用户干扰降至最低。安卓系统有 备份管理器服务,将所有可用的备份数据上传到云端。切换到新设备或卸载并重新安装应用将触发恢复操作,进而将数据复制到应用的数据目录中。

这种新行为允许您继续使用现有的备份服务调用。

要了解更多关于安卓棉花糖之前使用的 安卓备份服务的信息,请访问:

https://developer.android.com/guide/topics/data/backup.html

数据备份配置

我们有很多数据想要为用户备份,但是我们也不想备份所有的数据。假设我们都同意不备份用户的密码或其他敏感数据,但是如果您有一个基于用户使用的设备生成的特定应用配置,该怎么办?这也应该以类似于设备令牌的方式排除,例如谷歌云消息 ( GCM ) 和其他。我建议您找出您的应用持久保存哪些数据,以及这些数据是否应该并且能够与设备无关。

除了前面提到的自动排除的文件之外,您还可以配置正在备份的内容。这个配置应该通过android:fullBackupContent属性在你的应用清单中声明。您需要创建一个新的 XML 文件,该文件应该位于您的res/xml文件夹中,这将有备份您的应用数据的特定规则。

包括或不包括数据

XML 文件配置包括一批简单的include / exclude标记,这些标记指示您是否需要备份目录或特定文件。请记住,默认情况下,XML 是简化的,这意味着您可以备份所有可能的东西,除非有一个指令将它排除在您的 XML 之外。

另一种可能的配置是建设性配置,在这种配置中,您只指定要备份的内容,它们将被添加到备份中。这种配置行为是通过在您的 XML 中添加一个include标签来完成的,从那时起,它将保持建设性。

正如我们在示例中看到的,我们在应用的清单中指定了一个备份方案配置:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.yourapp.androidapp">
  <uses-sdk android:minSdkVersion="16" />
  <uses-sdk android:targetSdkVersion="23" />
  <app android:fullBackupContent="@xml/androidapp_backup_config">
  </app>
</manifest>

在我们的清单中声明文件之后,我们还需要在我们的res/xml文件夹中构造它;例如,看看以下内容:

<?xml version="1.0" encoding="utf-8"?>
<full-backup-content>
  <exclude domain="database" path="sensitive_database_name.db"/>
  <exclude domain="sharedpref" path="androidapp_shared_prefs_name"/>
  <exclude domain="file" path="some_file.file_Extension"/>
  <exclude domain="file" path="some_file.file_Extension"/>
</full-backup-content>

此示例备份配置仅排除特定数据的备份。所有其他文件都已备份。

备份配置语法

虽然你应该已经整理了你的应用的特定持久数据,我们可以检查应该在 XML 中的配置语法。配置 XML 文件的语法如下:

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

不要忘记阅读这里对每个属性和元素的解释:

  • <include>:当您想要将任何批准的分类中的资源专门添加到备份中时,您应该使用这个标记。请记住,每当您指定一个<include>标签时,备份行为将变为建设性的,并且系统仅备份用<include>标签指定的资源。
  • <exclude>:只要你想从备份中排除任何应用的资源,你就应该使用这个标签。如前所述,您应该排除敏感数据和应用的设备特定数据。这里的行为是这样的:系统备份你的应用的所有数据,除了用<exclude>标记指定的资源。
  • domain:这个出现在includeexclude标签上。它允许您声明要从备份中包括或排除的资源类型。该域具有特定的有效值,您可以从中进行选择:
    • root:这意味着资源应该在应用的root目录中
    • file:这意味着资源是位于Files目录中的文件,可以通过getFilesDir()方法访问
    • database:这意味着你的资源是一个数据库文件,可以通过getDatabasePath()方法或者SQLiteOpenHelper类来定位
    • sharedpref:这意味着你的资源是一个SharedPreferences对象,可以通过getSharedPreferences()方法访问
    • external:这意味着您的资源是位于外部存储器中的文件,该外部存储器位于通过getExternalFilesDir()方法访问的目录中
    • path:这是一个String路径,指向您希望包括在备份中或从备份中排除的资源

选择退出应用数据备份

在某些情况下,您可能会决定不希望在您的应用中使用应用数据备份功能。在这种情况下,您将能够通知系统您的应用已经选择退出。

使用以下命令将清单中的android:allowBackup属性设置为false:

android:allowBackup="false"

备份配置测试

到目前为止,您已经创建了一个备份配置,您可能(应该)测试它,并确保您的应用保存数据,恢复数据,并且没有任何问题。

设置备份日志

在您测试应用的配置之前,您可能想要启用日志记录;这是通过adb完成的,在这里您将解析器log属性设置为VERBOSE:

$ adb shell setprop log.tag.BackupXmlParserLogging VERBOSE

测试备份功能可以分为两部分:

  • 测试备份阶段
  • 测试恢复阶段

测试备份阶段

备份可以手动运行,但首先必须通过adb命令运行备份管理器:

$ adb shell bmgr run

备份管理器启动并运行后,我们可以通过adb触发备份阶段,并运行我们应用的包名作为<PACKAGE.NAME>参数:

$ adb shell bmgr fullbackup <PACKAGE.NAME>

测试恢复阶段

我们执行了备份阶段,一切顺利。现在,我们要测试恢复阶段,并验证所有备份的数据都已正确恢复,并且我们没有错过任何资源。我们手动运行恢复(必须在您的应用数据备份后进行)。这是通过adb shell 完成的,指定应用的包名作为<PACKAGE.NAME>参数:

$ adb shell bmgr restore <PACKAGE.NAME>

restore操作会在实际执行恢复操作之前停止您的应用并清除其数据。

故障排除

问题可以发生在任何地方,包括我们的案例。如果遇到问题,您应该通过导航至设置 | 备份&重置,工厂重置设备,打开和关闭备份来尝试清除数据:

Troubleshooting

您可以使用以下命令清除数据:

$ adb shell bmgr wipe <TRANSPORT> <PACKAGE.NAME>

<TRANSPORT>标签以com.google.android.gms/为前缀。要查看运输列表,您可以运行以下adb命令:

$ adb shell bmgr list transports

下面的截图是前面命令的结果:

Troubleshooting

重要字节

在我们进入下一章之前,让我们先浏览一下安卓应用备份功能中的几个重要的子主题。

系统备份不包括以下内容:

  • 通过getCacheDir()方法(API 1 及以上)位于CacheDir的文件
  • 通过getCodeCacheDir()方法(API 21 及以上)位于CodeCacheDir的文件
  • 通过getExternalFilesDir(String type)方法,位于外部存储器而非ExternalFilesDir中的文件,类型如下:
    • null为文件目录的根目录
    • 特定子文件夹/目录的任一类型:
      • android.os.Environment.DIRECTORY_MUSIC
      • android.os.Environment.DIRECTORY_PODCASTS
      • android.os.Environment.DIRECTORY_RINGTONES
      • android.os.Environment.DIRECTORY_ALARMS
      • android.os.Environment.DIRECTORY_NOTIFICATIONS
      • android.os.Environment.DIRECTORY_PICTURES
      • android.os.Environment.DIRECTORY_MOVIES
  • 通过getNoBackupFilesDir()方法(API 21 及以上)位于NoBackupFilesDir的文件

从备份中排除什么

虽然我们之前已经讨论过这一点,但您可能需要修改哪些应用数据适合备份。

在排除的数据中,您必须排除由服务器发布或在设备上生成的任何设备特定标识符,包括 GCM 注册令牌。

您还必须为任何帐户凭据或其他敏感信息添加排除逻辑。

备份代理和备份事件

你可以实现自己的BackupAgent属性,可以听事件。BackupAgent有几个回调可以覆盖,其中一个是onRestoreFinished()方法,在成功恢复后调用。除了android:backupAgent之外,你应该在你的清单中增加android:fullBackupOnly="true"属性;这将表明,虽然你的应用有一个BackupAgent属性,安卓棉花糖和其他设备将只执行全数据备份操作。

当您想要从您的 共享引用备份(设备特定的令牌、GCM 令牌等)中排除一些密钥时,这项技术可以派上用场。不需要将 SharedPreferences 分割成多个文件,只需在调用onRestoreFinished()时,在还原时移除密钥即可。

请记住,其他敏感数据无论如何都不应该备份。您可以在以下网址阅读更多关于BackupAgent的信息:

http://developer . Android . com/reference/Android/app/backup/backup agent . html

总结

安卓棉花糖为应用带来了出色的备份功能,减少了用户迁移到新设备时的摩擦。

在一个充满各种应用的世界中,最大限度地利用自动备份的优势可以带来更好的用户体验。该功能的目标是减轻负担,缩短使用用户喜爱的应用设置新设备所需的时间。

允许用户在新安装后只需一个密码提示就可以进入你的应用,这是一个很好的体验;自己试试吧!您可以查看包含的示例代码,或者访问 GitHub 存储库:

https://github.com/MaTriXy/apps_autobackup_example

在我们的下一章中,当我们展现安卓棉花糖的惊人之处时,我们将深入了解它的更多变化。**