com.android.backup是,Android Data Backup

The Basics

为了备份应用数据,你需要实现一个 backup agent. 它用来为BackupManager 提供你想要备份的数据,在你重新安装应用时恢复数据。BackupManager 通过backup transport 处理和云存储相关的数据业务,通过你的backup agent 处理设备上的数据相关的业务。

BackupAgent实现步骤:

在 manifest 文件中声明 android:backupAgent 属性。

通过backup服务注册你的应用。谷歌为大多数 Android 设备提供了 Android Backup Service,你需要通过这个服务注册你的应用。其他的云服务也需要注册。

定义你的 backup agent:

扩展 BackupAgent

重写 onBackup() onRestore()

扩展 BackupAgentHelper

需要使用多个helper对象自动完成备份及恢复。

会备份整个文件。

Declaring the Backup Agent in Your Manifest

在application标签中声明android:backupAgent.

...

android:backupAgent="MyBackupAgent">

...

android:restoreAnyVersion

默认值为false, 设为true 则会在该应用的任何版本恢复数据。

Registering for Android Backup Service

不同的设备对 backup 的支持不同。

android:backupAgent="MyBackupAgent">

...

android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" />

Extending BackupAgent

一般情况下,因为BackupAgentHelper比BackupAgent更方便,所以尽可能使用前者。

然而,如果有以下需求,还是要通过BackupAgent来实现:

对数据进行版本控制

并不想备份整个数据文件

备份数据库中的数据

如果你想要备份SharedPreferences和内部存储中的整个文件,简单地使用BackupAgentHelper即可。

Performing backup

oldState

上一次备份的状态,主要是FileDescriptor

// Get the oldState input stream

FileInputStream instream = new FileInputStream(oldState.getFileDescriptor());

DataInputStream in = new DataInputStream(instream);

try {

// Get the last modified timestamp from the state file and data file

long stateModified = in.readLong();

long fileModified = mDataFile.lastModified();

if (stateModified != fileModified) {

// The file has been modified, so do a backup

// Or the time on the device changed, so be safe and do a backup

} else {

// Don't back up because the file hasn't changed

return;

}

} catch (IOException e) {

// Unable to read state file... be safe and do a backup

}

data

要备份的数据,通过byte字节流的方式存储

// Create buffer stream and data output stream for our data

ByteArrayOutputStream bufStream = new ByteArrayOutputStream();

DataOutputStream outWriter = new DataOutputStream(bufStream);

// Write structured data

outWriter.writeUTF(mPlayerName);

outWriter.writeInt(mPlayerScore);

// Send the data to the Backup Manager via the BackupDataOutput

byte[] buffer = bufStream.toByteArray();

int len = buffer.length;

data.writeEntityHeader(TOPSCORE_BACKUP_KEY, len);

data.writeEntityData(buffer, len);

newState

本次备份的状态,作为下次备份时的oldState

Performing restore

data

用来恢复数据的 `BackupDataInput`.

appVersionCode

android:versionCode

newState

恢复后,需要把data里的ParcelFileDescriptor 写到newState中,它会以下次onBackup的oldState被用到。

@Override

public void onRestore(BackupDataInput data, int appVersionCode,

ParcelFileDescriptor newState) throws IOException {

// There should be only one entity, but the safest

// way to consume it is using a while loop

while (data.readNextHeader()) {

String key = data.getKey();

int dataSize = data.getDataSize();

// If the key is ours (for saving top score). Note this key was used when

// we wrote the backup entity header

if (TOPSCORE_BACKUP_KEY.equals(key)) {

// Create an input stream for the BackupDataInput

byte[] dataBuf = new byte[dataSize];

data.readEntityData(dataBuf, 0, dataSize);

ByteArrayInputStream baStream = new ByteArrayInputStream(dataBuf);

DataInputStream in = new DataInputStream(baStream);

// Read the player name and score from the backup data

mPlayerName = in.readUTF();

mPlayerScore = in.readInt();

// Record the score on the device (to a file or something)

recordScore(mPlayerName, mPlayerScore);

} else {

// We don't know this entity key. Skip it. (Shouldn't happen.)

data.skipEntityData();

}

}

// Finally, write to the state blob (newState) that describes the restored data

FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor());

DataOutputStream out = new DataOutputStream(outstream);

out.writeUTF(mPlayerName);

out.writeInt(mPlayerScore);

}

Extending BackupAgentHelper

SharedPreferencesBackupHelper

FileBackupHelper

Backing up SharedPreferences

public class MyPrefsBackupAgent extends BackupAgentHelper {

// The name of the SharedPreferences file

static final String PREFS = "user_preferences";

// A key to uniquely identify the set of backup data

static final String PREFS_BACKUP_KEY = "prefs";

// Allocate a helper and add it to the backup agent

@Override

public void onCreate() {

SharedPreferencesBackupHelper helper =

new SharedPreferencesBackupHelper(this, PREFS);

addHelper(PREFS_BACKUP_KEY, helper);

}

}

Note: SharedPreferences are threadsafe, so you can safely read and write the shared preferences file from your backup agent and other activities.

Backing up other files

public class MyFileBackupAgent extends BackupAgentHelper {

// The name of the file

static final String TOP_SCORES = "scores";

static final String PLAYER_STATS = "stats";

// A key to uniquely identify the set of backup data

static final String FILES_BACKUP_KEY = "myfiles";

// Allocate a helper and add it to the backup agent

@Override

public void onCreate() {

FileBackupHelper helper = new FileBackupHelper(this,

TOP_SCORES, PLAYER_STATS);

addHelper(FILES_BACKUP_KEY, helper);

}

}

非线程安全,需要手动加锁

// Object for intrinsic lock

static final Object sDataLock = new Object();

try {

synchronized (MyActivity.sDataLock) {

File dataFile = new File(getFilesDir(), TOP_SCORES);

RandomAccessFile raFile = new RandomAccessFile(dataFile, "rw");

raFile.writeInt(score);

}

} catch (IOException e) {

Log.e(TAG, "Unable to write to file");

}

@Override

public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,

ParcelFileDescriptor newState) throws IOException {

// Hold the lock while the FileBackupHelper performs backup

synchronized (MyActivity.sDataLock) {

super.onBackup(oldState, data, newState);

}

}

@Override

public void onRestore(BackupDataInput data, int appVersionCode,

ParcelFileDescriptor newState) throws IOException {

// Hold the lock while the FileBackupHelper restores the file

synchronized (MyActivity.sDataLock) {

super.onRestore(data, appVersionCode, newState);

}

}

Checking the Restore Data Version

android:versionCode

BackupManager恢复数据前会检查versionCode字段,如果待恢复的版本高于当前应用版本,BackupManager不会调用onRestore()来恢复数据。

android:restoreAnyVersion

设定trueorfalse指明你是否希望通过应用的版本来决定是否恢复数据。设为true,那么BackupManager将不会去检查android:versionCode,而是调用你的onRestore()方法。

你可以通过下面的方法来获取appVersionCode.

PackageInfo info;

try {

String name = getPackageName();

info = getPackageManager().getPackageInfo(name,0);

} catch (NameNotFoundException nnfe) {

info = null;

}

int version;

if (info != null) {

version = info.versionCode;

}

Requesting Backup

使用dataChanged()来请求备份,这个不会立即执行,会在未来某个合适的时间内执行

开发时使用bmgr工具来随时备份

Requesting Restore

自动检测备份数据

requestRestore()

bmgr工具

Testing Your Backup Agent

安装应用

确定备份功能可用

使用模拟器

adb shell bmgr enable true

If using a device, open the system Settings, select Backup & reset, then enable Back up my data and Automatic restore.

在用户改变数据的地方调用dataChanged()

然后执行:adb shell bmgr backup your.package.name

初始化备份操作

adb shell bmgr run

卸载应用

adb uninstall your.package.name

重新安装

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值