继承BackupAgentHelper类

如果要备份完整的文件(既可以是SharedPreferences文件也可以是内部存储文件),那么就应该使用BackupAgentHelper类来构建备份代理。用BackupAgentHelper类构建的备份代理比继承BackupAgent类所需要的代码要少的多,因为它不需要实现onBackup()和onRestore()方法。

BackupAgentHelper类的实现必须使用一个或多个备份帮助器。备份帮助器BackupAgentHelper类的一个特殊组件,它对特定类型的数据执行备份和恢复操作。Android框架目前提供两种不同类型的帮助器:

1. 备份SharedPreferences文件用的SharedPreferencesBackupHelper类

2. 备份内部存储器中文件的FileBackupHelper类。

可以在BackupAgentHelper类中包含多个帮助器,但是每种数据类型只能有一个帮助器。也就是说,如果有多个SharedPreferences文件,那么也只需要一个SharedPreferencesBackupHelper类。

对于每个要在BackupAgentHelper的实现类中添加的的帮助器,在实现类的onCreate()方法执行期间必须做以下事情:

1. 实例化一个帮助器类的实例,在这个类的构造器中,必须指定相应的要备份的文件。

2. 调用addHelper()方法,把帮助器添加给BackupAgentHelper的实现类。

备份SharedPreferences数据

当实例化了一个SharedPreferencesBackupHelper帮助器时,必须包含一个或多个SharedPreferences的文件名。

例如,要备份一个名叫“user_preferences”的SharedPreferences文件,一个完成的备份代理帮助器的实现如下:

publicclassMyPrefsBackupAgentextendsBackupAgentHelper{
    // The name of the SharedPreferences file
    staticfinalString PREFS ="user_preferences";

// A key to uniquely identify the set of backup data
    staticfinalString PREFS_BACKUP_KEY ="prefs";

// Allocate a helper and add it to the backup agent
    @Override
    publicvoid onCreate(){
        SharedPreferencesBackupHelper helper =newSharedPreferencesBackupHelper(this, PREFS);
        addHelper(PREFS_BACKUP_KEY, helper);
    }
}

以上代码就是一个完整的备份代理,SharedPreferencesBackupHelper类包含了备份和恢复SharedPreferences文件所需的所有代码。

当备份管理器调用onBackup()和onRestore()时,BackupAgentHelper对象会调用备份帮助器来对指定的文件执行备份和恢复操作。

注意:SharedPreferences对象是线程安全的,因此可以在备份代理和其他的Activity中安全的读写共享偏好文件。

备份其他文件

在实例化一个FileBackupHelper类时,必须要包含一个或多个保存的应用程序的内部存储器中的文件名称。

例如,要备份两个名叫“scores”和“stats”的文件,备份代理应该像如下代码这样使用备份代理帮助器:

publicclassMyFileBackupAgentextendsBackupAgentHelper{
    // The name of the SharedPreferences file
    staticfinalString TOP_SCORES ="scores";
    staticfinalString PLAYER_STATS ="stats";

// A key to uniquely identify the set of backup data
    staticfinalString FILES_BACKUP_KEY ="myfiles";

// Allocate a helper and add it to the backup agent
    void onCreate(){
        FileBackupHelper helper =newFileBackupHelper(this, TOP_SCORES, PLAYER_STATS);
        addHelper(FILES_BACKUP_KEY, helper);
    }
}

FileBackupHelpler类包含了备份和恢复内部存储器中的文件的所有必需代码。

但是,读写内部存储器上的文件不是线程安全的,要确保备份代理与Activity不会同时读写文件,必需在每次执行读写操作时使用同步语句。例如,在任何一个读写内部存储器文件的Activity中,需要在同步语句中使用一个对象作为内部锁,如:

// Object for intrinsic lock
static final Object[] sDataLock = new Object[0];

每次读写文件时,都要用这个锁来创建一个同步语句。如,下面代码中的锁定语句用于把最后的成绩写入一个游戏文件:

try{
    synchronized(MyActivity.sDataLock){
        File dataFile =newFile(getFilesDir(), TOP_SCORES);
        RandomAccessFile raFile =newRandomAccessFile(dataFile,"rw");
        raFile.writeInt(score);
    }
}catch(IOException e){
    Log.e(TAG,"Unable to write to file");
}

应该使用相同的锁来锁定读数据的同步语句。

然后,在BackupAgentHelper的实现类中,必须重写onBackup()和onRestore()方法,用相同的内部锁来同步备份和恢复操作。例如,上面的MyFileBackupAgent类需要下面的方法:

@Override
publicvoid onBackup(ParcelFileDescriptor oldState,BackupDataOutput data,
          ParcelFileDescriptor newState)throwsIOException{
    // Hold the lock while the FileBackupHelper performs backup
    synchronized(MyActivity.sDataLock){
        super.onBackup(oldState, data, newState);
    }
}

@Override
publicvoid onRestore(BackupDataInput data,int appVersionCode,
        ParcelFileDescriptor newState)throwsIOException{
    // Hold the lock while the FileBackupHelper restores the file
    synchronized(MyActivity.sDataLock){
        super.onRestore(data, appVersionCode, newState);
    }
}

也就是说,需要你做的所有事情就是在onCreate()方法中把自己的FileBackupHelper的实现类对象添加到BackupAgentHelper的实现对象中,并重写BackupAgentHelper实现类的onBackup()和onRestore()方法。

检查恢复数据的版本

当备份管理器把数据保存到云端时,它会自动包含应用程序在清单文件的android:versionCode属性中定义的应用程序的版本号。在备份管理器调用备份代理来恢复数据之前,它会查看应用程序的android:versionCode属性中的版本号,并把它跟备份数据中记录的版本号进行比较,如果恢复数据集中记录的版本号比设备上当前应用程序的版本号新,那么说明用户使用了低版本的应用程序。因此备份管理器会中断恢复操作,并不调用onRestore()方法,因为在低版本的应用上恢复数据集被认为是毫无意义的。

可以使用android:restoreAnyVersion属性来改变这种行为。这个属性值可以true也可以是false,它用来指定应用程序的数据恢复操作是否要忽略版本号的设置。默认值是false。如果把这个属性定义为true,那么备份管理器会忽略android:versionCode属性,并在所有的情况中调用onRestore()方法。在重写的onRestore()方法中能够手动的检查版本号的差异,并采取必要的步骤让数据兼容,以避免版本冲突。

onRestore()方法的appVersionCode参数包含要恢复的数据集的版本号,它会在数据恢复操作期间为处理版本差异提供帮助。然后,用PackageInfo.versionCode成员属性来查询当前应用程序的版本号,如:

PackageInfo info;
try{
    String name =getPackageName();
    info =getPackageManager().getPackageInfo(name,0);
}catch(NameNotFoundException nnfe){
    info =null;
}

int version;
if(info !=null){
    version = info.versionCode;
}

然后就可以把从PackageInfo中获取的版本号与onRestore()方法中传入的版本号进行比较。

警告:必须理解设置android:restoreAnyVersion属性为true时给应用程序所带来的影响。如果在onRestore()方法执行期间,支持备份的每个应用程序版本没有针对数据格式的变化来使正确的账号,那么恢复到设备上的数据格式可能与设备上当前的应用程序版本不兼容。

请求备份数据

通过调用dataChanaged()方法,能够在任何时候请求备份操作。这个方法会通知备份管理器使用备份代理来数据备份操作。然后,备份管理器会在未来适当时机调用备份代理的onBackup()方法。通常,应该在每次数据变化时来请求备份操作(如因用户改变了应用程序偏好而执行的备份操作)。如果连续多次的调用了dataChanged()方法,那么在备份管理器请求备份代理之前,备份代理依然只会接受一次对onBackup()方法的调用。

注意:在开发应用程序时,能够使用bmgr工具来请求立即执行一个备份操作。

请求恢复数据

在应用程序的普通生存期间,不应该请求数据恢复操作。系统会自动检查备份数据,并在应用程序被安装的时候执行数据恢复操作。但是如果需要,通过调用requestRestore()方法可以手动的请求一个数据恢复操作。在这种情况下,备份管理器会调用onRestore()方法的实现,来恢复当前备份数据集中的数据。

注意:在开发应用程序时,用bmgr工具能够请求一个数据恢复的操作。

测试备份代理

一旦实现了备份代理,就能够使用bmgr工具来测试数据备份和数据恢复功能:

1. 把应用程序安装在一个合适的Android系统镜像上。

如果使用模拟器,要创建一个使用Android2.2(API级别8)的AVD;

如果使用一个实际设备,那么设备必须运行在Android2.2或更高的版本上,并且有内置的Google Play。

2. 确保备份功能可用

如果使用模拟器,用tools/路径下的下列命令来启用数据备份功能:

adb shell bmgr enable true

如果使用实际的设备,那么打开系统的Settings应用,选择Privacy,然后启用Back up my data和Automatic restore。

3. 打开应用程序并初始化一些数据

如果在应用程序中正确的实现了备份处理,那么每次数据变化时都应该请求一个备份操作。例如每次用户改变数据时,应用程序都应该调用dataChanged()方法,它会把备份请求添加到备份管理器的队列中。为了达到测试的目的,也可以用下列的bmgr命令来发起一个备份请求:

adb shell bmgr backup your.package.name

4. 初始化备份操作:

adb shell bmgr run

这样会强制备份管理器来执行它的队列中的所有备份请求。

5. 卸载应用程序

adb uninstall your.package.name

6. 重装应用程序

如果备份代理成功的执行了,那么所有在上述步骤4中初始化的数据都会被恢复。

Android数据存储---数据备份(Data Backup)(三)相关推荐

  1. android 数据文件存储,实例详解Android文件存储数据方式

    总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.下面通过本文给大家介绍android文件存储数据方式. 1.文件存储数据使用了java中的io操作来进行文件的保存和读取,只不 ...

  2. 大数据存储与备份,迫在眉睫!

    随着互联网信息技术的发展,如今的社会和人际圈已然成为一个信息化的圈子,而基于这些信息和技术所建立起来的信息系统正改变着人们的工作和生活方式,至今,大数据已经逐渐开始形成. 大数据存储备份 然而凡事都有 ...

  3. 数据存储与备份管理解决方案

    一.概述 现在,如何有效地防范系统突发事件,在尽可能低的运作成本和拥有成本的前提下,提高数据的可靠性和可用性,已成为企业信息化工作急需解决的内容和关键性问题. TSM(Tivoli Storage M ...

  4. 华为云大数据存储的冗余方式是三副本_华为TaurusDB技术解读(转载)

    近日,华为云自研关系型数据库 Taurus 公开亮相.作为华为云自研的最新一代云原生分布式数据库,Taurus 完全兼容 MySQL 8.0,采用计算与存储分离.日志即数据的架构设计,支持 1 写 1 ...

  5. 华为云大数据存储的冗余方式是三副本_揭秘!10+位DBA大神测评华为云DDS增强版实感...

    数据库.操作系统.中间件并称为核心基础软件,在 IT 软件堆栈中起到中流砥柱的作用.今天运行的绝大多数企业应用软件都离不开数据库的支持. 随着移动互联网.物联网.云计算.大数据等新技术爆发式发展,图片 ...

  6. 华为云大数据存储的冗余方式是三副本_大数据显示华为云DDS增强版实感卓越

    数据库.操作系统.中间件并称为核心基础软件,在 IT 软件堆栈中起到中流砥柱的作用.今天运行的绝大多数企业应用软件都离不开数据库的支持. 随着移动互联网.物联网.云计算.大数据等新技术爆发式发展,图片 ...

  7. 华为云大数据存储的冗余方式是三副本_大数据入门:HDFS数据副本存放策略

    大数据处理当中,数据储存始终是一个重要的环节,从现阶段的市场现状来说,以Hadoop为首的大数据技术框架,仍然占据主流地位,而Hadoop的HDFS,在数据存储方面,仍然得到重用.今天的大数据入门分享 ...

  8. 华为云大数据存储的冗余方式是三副本_阿里云大数据产品 | 大数据计算

    阿里云大数据计算产品包括MaxCompute.E-MapReduce和实时计算(Alibaba Cloud Realtime Compute). 一.MaxCompute 1.MaxCompute概述 ...

  9. 数据存储之 SQLite 数据库操作(三)

    上一讲中我们讲到了SQLite数据库的操作方法 [数据存储之SQLite数据库操作(二)],我们主要是以SQL语句对数据库进行增删改查,这一讲我们来学习一下 Android 建议的对数据库的操作方法 ...

  10. 华为云大数据存储的冗余方式是三副本_华为OceanStor分布式存储,引领智能时代大数据创新...

    云+AI的智能时代已经到来,计算存储融合的大数据架构由于存在计算存储不能灵活扩展.不同大数据集群间资源利用率不均且数据无法共享.三副本存储利用率低且无法和AI应用高效联动等问题,已经无法满足云+AI时 ...

最新文章

  1. 50 道 CSS 基础面试题及答案
  2. ecshop调用指定ID分类下的文章列表(指定分类下的文章)
  3. chrome的全局搜索快捷键
  4. python可以直接打印中午吗_Python print不能立即打印的解决方式
  5. 属性提取器:获取ListView即时更新其元素的最佳方法
  6. [HDU]1723Distribute Message
  7. matlab测量液体液位,基于MATLAB三容水箱液位控制系统.doc
  8. 云小课|云数据库RDS实例连接失败了?送你7大妙招轻松应对
  9. 垃圾回收器之标记擦除法
  10. mac netbeans java_在macOS上不安装JDK的情况下安装Netbeans
  11. 做生意、做营销常犯的10个错误和对策
  12. sql server 群集_SQL Server群集索引概述
  13. 拷贝data/data/包名/files文件记下所有文件及文件夹到本地sdcard根目录teddyData_files文件夹下...
  14. shell 脚本实战笔记(7)--集群网络相关知识和环境搭建
  15. 波形捕捉:(3)捕捉设备性能
  16. 快速入手光学字符识别控件Aspose.OCR!学会使用C#以编程方式对图像执行OCR
  17. json接口(使用,以及自定义)
  18. 培训linux系统下载,非常好的Linux培训教程集合下载
  19. 错误 C1041 无法打开程序数据库“xxx\Debug\core142.pdb”
  20. vscode自定义消息配置

热门文章

  1. 知识体系之APUE/内核编程
  2. 程序设计基础学习总结
  3. mysql+地图网格数据下载_离线地图
  4. ADDS:关于用户账户名称辨析
  5. 基于Qt的ARM-Linux系统测试工具
  6. Win10怎么禁止开机自动运行语音识别
  7. 公司招聘专员爆头痛哭,求职者再拒绝我的邀请我就要。。。
  8. Python-Django毕业设计安卓电影院售票管理APP论文(程序+LW)
  9. VS Code || Visual Studio Code 修改、添加背景图片的方式
  10. 判断二叉树是否为满二叉树