全面复盘Android开发者容易忽视的Backup功能 _ 创作者训练营第二期

这些数据耗费了我们很多时间和精力,对我们而言极为重要。如果我们的设备换代了或者重新安装了某个应用,之前使用的数据如果能自动保留,那将是非常出色的用户体验。而保留数据的第一步则在于Backup环节。

2.2 数据来源

用户的数据可以笼统地划分为三块:登录账号相关的身份数据、系统设置相关的偏好以及各App的数据。这三块数据的类型不同、位置不同,进而导致Backup的实现也不同。

cmd-markdown-logo

  • App数据:应用内部的图片,视频等数据。这是我们尤为关心的数据,如何安全完整地转移这些数据是Backup功能的目标所在,也是本文需要讲解的核心内容
  • 身份数据:用户登录的身份数据。可以通过Smart Lock或Account Transfer API在设备间立即恢复登录状态
  • 设置偏好:系统设置App和SettingProvider将记录用户的偏好数据,甚至包括用户授予App的权限记录。系统将针对这些设置数据备份和恢复

2.3 备份对象

我们知道可以将数据存放在App目录,也可以存放于公共目录。但随着Android系统针对公共目录的限制愈加严格,将数据存放到App自己的目录显得更加合理。

App自身目录的这块数据顺理成章地成为Backup功能的主要对象,按照文件的类型可以细分如下。

类型 路径 取得对应文件的API
data /data/data/com.xxx/ getDataDir()/getDir()
files /data/data/com.xxx/files/ getFilesDir()
databases /data/data/com.xxx/databases/ getDatabasePath()
sharedpreferences /data/data/com.xxx/sp/ getSharedPreferences()

注意:

  • 放置在外部存储空间中的文件也是支持的,这里不再赘述
  • cache、nobackup等目录下的文件不在Backup对象内

Backup操作从最外层的data目录开始,按照文件单位逐个读取逐个备份。目录内的文件一般按照文件名的顺序进行备份,但这个顺序无法保证,取决于File#list() API的结果。

graph TD
data --> files --> databases --> sharedpreferences

2.4 如何开启

在Manifest文件里使用allowBackup属性可以控制Backup功能的开关。这个属性早在Android 1.6(API 4)的时候便引入了,起初默认是关闭的。

allowBackup Added in API level 4 Whether to allow the application to participate in the backup and restore infrastructure. If this attribute is set to false, no >backup or restore of the application will ever be performed, even by a full-system backup that would otherwise cause all >application data to be saved via adb. The default value of this attribute is true.

可能是Android设备火了,备份恢复的需求越来越大,自Android 6.0之后默认值变成了true,即默认将支持Backup功能。

2.5 开启的隐患

allowBackup属性开启的话,开发者使用几个简单的adb命令就可以将应用的数据备份和恢复。意味着自己的数据被转移到别人的设备上是非常简单的,这无疑造成了具大的安全隐患。

后面的实战将会揭晓控制备份和恢复的诸多可能,比如在恢复的逻辑里加入了限制使得恶意的恢复失败。但即便在恢复阶段拦截了,备份的ab文件仍掌握在别人手里,仍不稳妥。因为通过破解备份文件也可以阅读到部分甚至全部内容。

所以涉及到私密数据的App最好将该属性关闭,自行考虑数据的同步方式,比如通过账号系统恢复。

这个属性曾经引发安全隐患,详情可参考:

blog.csdn.net/zihao2012/a…

2.6 备份模式

Android 6.0之前Backup功能只有键值对备份(Key-value Backup)这一种模式,而且默认是关闭的。

想要打开键值对备份功能得将allowBackup属性设置为true,并指定BackupAgent实现,即明确地告知诉Backup功能每个文件按照什么key备份到Android Backup Service。简单来讲,必须给Backup功能提供一个备份文件的映射关系,好让它知道备份的源头和恢复的目标。

6.0之后allowBackup属性默认为true,但打开的不是键值对备份,而是新引入的自动备份(Auto Backup)。自动备份模式执行傻瓜式的全体备份和恢复,可供备份文件存放的空间更大,便捷够用更推荐。。

两个模式在备份的频次、文件的存放位置、恢复的执行时机等细节都很不一样。

备份模式 键值对备份 自动备份
支持版本 Android 2.2 Android 6.0
开关办法 默认关闭,需手动开启allowBackup并指定BackupAgent 默认开启,关闭需要将allowBackup置为false
备份定制 BackupAgent里指定备份和恢复的文件 可以通过XML配置备份和不备份的文件列表,也可以通过BackupAgent改写备份恢复的逻辑,定制性高
备份时机 需要App调用API手动发起备份 自动进行,大约每天一次
备份的托管位置 Android Backup Service/Google服务器 Google Drive云盘
备份限制 上限只有5M 上限有25M
恢复时机 APK安装的时候自动恢复,也可以调用API手动发起恢复 APK安装的时候自动恢复
原理细节 回调到BackupAgent的onBackup()和onRestore() 回调到BackupAgent的onFullBackup()和onRestoreFile()

2.7 备份的托管位置

使用键值对模式备份的文件托管在Google服务器(Android Backup Service),Google承诺将会加密传输这些数据,并尊重隐私条款。同时在App关闭Backup功能的时候删除这些备份,可以放心使用。

如果采用了默认的自动备份模式,那数据存放在Google Drive云盘。云盘拥有自己的账号系统,使用的是账号级别的加密保护,更为安全。

2.8 实现原理

那Android系统是如何实现Backup和Restore功能的呢?

在解答这个问题之前,我们先思考下如果你是Google开发者,你会怎么实现?

这里有个ContentProvider方案。简言之,使用一个统一调度的App通过ContentProvider组件向各个实现了特定Uri或Permission的ContentProvider App发出读写数据的请求。

  • 各App通过ContentProvider将需要备份的Data、File、DB以及SP文件传输出去,调度App收集到包名为单位的备份文件集合,加密后上传到服务器或内存卡
  • 恢复则是调度App将文件解密之后通过ContentProvider再回传给各App,各App自行执行恢复的逻辑

但这个方案有点缺憾。对于大部分App来说文件全部备份和恢复就行了,不需要搞特别的定制。但实际情况是需要支持备份恢复的话,就得各自实现一套ContentProvider去做文件的收集和覆盖。

而Google采取的方案是这样的。默认认为每个App都支持Backup功能,然后给App提供同样的BackupAgent去执行自动备份和恢复的处理。当App存在特别定制的需求的时候可以指定扩展的BackupAgent逻辑,更加灵活高效。

内部的实现原理简述如下。

  1. 系统服务BMS(BackupManagerService)收到BackupManager API发起的备份/恢复请求后,该服务将通过IBackupTransport和Cloud端建立连接
  2. BMS通过持有的BackupHandler依据操作参数启动相应的Backup或Restore线程
  3. 任务线程通过AppBackupUtils检查该App是否支持Backup/Restore
  4. 之后依据备份模式创建对应的Engine并通过通过IBackupAgent向App发起实际的操作请求
  5. BackupAgent将按照对应模式去读取或写入文件

在这里插入图片描述

3. 发起、调试和解密Backup

3.1 Backup/Restore的发起

3.1.1 代码方式

选取了键值对备份模式的话,需要在数据发生变动的时候手动发起备份。SDK提供了API:BackupManager的dataChanged()。调用之后BackupManager将调度备份请求在适当的时机发起备份处理。

事实上BackupManager还提供了requestRestore()供我们手动发起恢复,API的返回值将告诉我们是否将要执行恢复操作。这个API发起的恢复结束之后不会KILL进程,存在造成数据错乱

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值