diff options
author | Christopher Tate <ctate@google.com> | 2010-04-12 16:23:35 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2010-04-12 16:23:35 -0700 |
commit | 5c7a69c3d6f41f60f4bfc3f7e3123941d382f3a7 (patch) | |
tree | f01b628b4bb193615e57692c38003af2dab2d108 | |
parent | 9aa74f59422bdf43bb75f52235fec04b08f2f971 (diff) | |
parent | 6a75d6850c77fb48daba7700621856605ab60569 (diff) | |
download | frameworks_base-5c7a69c3d6f41f60f4bfc3f7e3123941d382f3a7.zip frameworks_base-5c7a69c3d6f41f60f4bfc3f7e3123941d382f3a7.tar.gz frameworks_base-5c7a69c3d6f41f60f4bfc3f7e3123941d382f3a7.tar.bz2 |
am 6a75d685: am 7e8614a5: Merge "SDK: more backup/restore documentation work" into froyo
Merge commit '6a75d6850c77fb48daba7700621856605ab60569' into kraken
* commit '6a75d6850c77fb48daba7700621856605ab60569':
SDK: more backup/restore documentation work
-rw-r--r-- | core/java/android/app/backup/BackupAgent.java | 100 | ||||
-rw-r--r-- | core/java/android/app/backup/BackupAgentHelper.java | 5 | ||||
-rw-r--r-- | core/java/android/app/backup/BackupDataInput.java | 72 | ||||
-rw-r--r-- | core/java/android/app/backup/BackupDataOutput.java | 40 | ||||
-rw-r--r-- | core/java/android/app/backup/BackupHelper.java | 9 | ||||
-rw-r--r-- | core/java/android/app/backup/BackupManager.java | 35 | ||||
-rw-r--r-- | core/java/android/app/backup/FileBackupHelper.java | 24 | ||||
-rw-r--r-- | core/java/android/app/backup/SharedPreferencesBackupHelper.java | 40 | ||||
-rw-r--r-- | core/res/res/values/attrs_manifest.xml | 4 | ||||
-rw-r--r-- | docs/html/guide/topics/manifest/application-element.jd | 54 |
10 files changed, 303 insertions, 80 deletions
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index f9dcab8..0bb2cb5 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -29,18 +29,57 @@ import android.util.Log; import java.io.IOException; /** - * This is the central interface between an application and Android's settings - * backup mechanism. Any implementation of a backup agent should perform backup - * and restore actions in + * {@link android.app.backup.BackupAgent} is the central interface between an + * application and Android's data backup infrastructure. An application that wishes + * to participate in the backup and restore mechanism will declare a subclass of + * {@link android.app.backup.BackupAgent}, implement the * {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)} - * and {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor)} - * respectively. + * and {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor)} methods, + * and provide the name of its agent class in the AndroidManifest.xml file via + * the <application> tag's android:backupAgent attribute. * <p> - * A backup agent based on convenient helper classes is available in - * {@link android.app.backup.BackupAgentHelper} for less complex implementation - * requirements. + * <b>Basic Operation</b> * <p> - * STOPSHIP write more documentation about the backup process here. + * When the application makes changes to data that it wishes to keep backed up, + * it should call the + * {@link android.app.backup.BackupManager#dataChanged() BackupManager.dataChanged()} method. + * This notifies the Android backup manager that the application needs an opportunity + * to update its backup image. The backup manager, in turn, will then schedule a + * backup pass to be performed at an opportune time. + * <p> + * Restore operations are typically only performed when applications are first + * installed on a device. At that time, the operating system checks to see whether + * there is a previously-saved data set available for the application, and if so, + * begins an immediate restore pass to deliver that data as part of the installation + * process. + * <p> + * When a backup or restore pass is run, the application's process will be launched + * (if not already running), the manifest-declared agent class instantiated within + * that process, and the agent's {@link #onCreate()} method invoked. This prepares the + * agent instance to run the actual backup or restore logic. At this point the + * agent's + * {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup()} or + * {@link #onRestore(BackupDataInput, int, ParcelFileDescriptor) onRestore()} method will be + * invoked as appropriate for the operation being performed. + * <p> + * A backup data set consists of one or more "entities," flattened binary data records + * that are each identified with a key string unique within the data set. Adding a + * record to the active data set, or updating an existing record, are done by simply + * writing new entity data under the desired key. Deleting an entity from the data set + * is done by writing an entity under that key with header specifying a negative data + * size, and no actual entity data. + * <p> + * <b>Helper Classes</b> + * <p> + * An extensible agent based on convenient helper classes is available in + * {@link android.app.backup.BackupAgentHelper}. That class is particularly + * suited to handling of simple file or {@link android.content.SharedPreferences} + * backup and restore. + * + * @see android.app.backup.BackupManager + * @see android.app.backup.BackupAgentHelper + * @see android.app.backup.BackupDataInput + * @see android.app.backup.BackupDataOutput */ public abstract class BackupAgent extends ContextWrapper { private static final String TAG = "BackupAgent"; @@ -50,9 +89,22 @@ public abstract class BackupAgent extends ContextWrapper { super(null); } + /** + * Provided as a convenience for agent implementations that need an opportunity + * to do one-time initialization before the actual backup or restore operation + * is begun. + * <p> + * Agents do not need to override this method. + */ public void onCreate() { } + /** + * Provided as a convenience for agent implementations that need to do some + * sort of shutdown process after backup or restore is completed. + * <p> + * Agents do not need to override this method. + */ public void onDestroy() { } @@ -65,18 +117,26 @@ public abstract class BackupAgent extends ContextWrapper { * cases, a representation of the final backup state after this pass should * be written to the file pointed to by the file descriptor wrapped in * <code>newState</code>. + * <p> + * Each entity written to the {@link android.app.backup.BackupDataOutput} + * <code>data</code> stream will be transmitted + * over the current backup transport and stored in the remote data set under + * the key supplied as part of the entity. Writing an entity with a negative + * data size instructs the transport to delete whatever entity currently exists + * under that key from the remote data set. * * @param oldState An open, read-only ParcelFileDescriptor pointing to the * last backup state provided by the application. May be * <code>null</code>, in which case no prior state is being * provided and the application should perform a full backup. * @param data A structured wrapper around an open, read/write - * ParcelFileDescriptor pointing to the backup data destination. + * file descriptor pointing to the backup data destination. * Typically the application will use backup helper classes to * write to this file. * @param newState An open, read/write ParcelFileDescriptor pointing to an * empty file. The application should record the final backup - * state here after writing the requested data to dataFd. + * state here after writing the requested data to the <code>data</code> + * output stream. */ public abstract void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException; @@ -84,8 +144,7 @@ public abstract class BackupAgent extends ContextWrapper { /** * The application is being restored from backup and should replace any * existing data with the contents of the backup. The backup data is - * provided in the file descriptor pointed to by the - * {@link android.app.backup.BackupDataInput} instance <code>data</code>. Once + * provided through the <code>data</code> parameter. Once * the restore is finished, the application should write a representation of * the final state to the <code>newState</code> file descriptor. * <p> @@ -98,17 +157,18 @@ public abstract class BackupAgent extends ContextWrapper { * before proceeding. * * @param data A structured wrapper around an open, read-only - * ParcelFileDescriptor pointing to a full snapshot of the - * application's data. Typically the application will use helper - * classes to read this data. - * @param appVersionCode The android:versionCode value of the application - * that backed up this particular data set. This makes it easier - * for an application's agent to distinguish among several + * file descriptor pointing to a full snapshot of the + * application's data. The application should consume every + * entity represented in this data stream. + * @param appVersionCode The + * {@link android.R.styleable#AndroidManifest_versionCode android:versionCode} + * value of the application that backed up this particular data set. This + * makes it possible for an application's agent to distinguish among any * possible older data versions when asked to perform the restore * operation. * @param newState An open, read/write ParcelFileDescriptor pointing to an * empty file. The application should record the final backup - * state here after restoring its data from dataFd. + * state here after restoring its data from the <code>data</code> stream. */ public abstract void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) diff --git a/core/java/android/app/backup/BackupAgentHelper.java b/core/java/android/app/backup/BackupAgentHelper.java index 7b6be23..788b1b5 100644 --- a/core/java/android/app/backup/BackupAgentHelper.java +++ b/core/java/android/app/backup/BackupAgentHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,6 +30,9 @@ import java.io.IOException; * have the BackupAgentHelper implementation process the data. * <p> * STOPSHIP: document! + * + * @see FileBackupHelper + * @see SharedPreferencesBackupHelper */ public class BackupAgentHelper extends BackupAgent { static final String TAG = "BackupAgentHelper"; diff --git a/core/java/android/app/backup/BackupDataInput.java b/core/java/android/app/backup/BackupDataInput.java index 2da0c11..976e0c9 100644 --- a/core/java/android/app/backup/BackupDataInput.java +++ b/core/java/android/app/backup/BackupDataInput.java @@ -20,7 +20,41 @@ import java.io.FileDescriptor; import java.io.IOException; /** - * STOPSHIP: document! + * BackupDataInput is the structured interface used for passing the contents of + * a backup data set to an application's {@link BackupAgent} class in its + * {@link BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor)} + * method. The data is presented as a set of "entities," each + * representing one named record as previously stored by the agent's + * {@link BackupAgent#onBackup(android.os.ParcelFileDescriptor, BackupDataOutput, android.os.ParcelFileDescriptor)} + * implementation. An entity is composed of a descriptive header plus a + * byte array that holds its raw data. + * <p> + * The agent must consume every entity in the data stream, otherwise the + * restored state of the application will be incomplete. + * <p> + * <b>Example</b> + * <p> + * A typical + * {@link BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) BackupAgent.onRestore(data, appVersionCode, newState)} + * implementation might be structured something like this: + * <pre> + * while (data.readNextHeader()) { + * String key = data.getKey(); + * int dataSize = data.getDataSize(); + * + * if (key.equals(MY_BACKUP_KEY_ONE)) { + * // process this kind of record here + * byte[] buffer = new byte[dataSize]; + * data.readEntityData(buffer, 0, dataSize); // reads the entire entity at once + * + * // now 'buffer' holds the raw data and can be processed however + * // the agent wishes + * processBackupKeyOne(buffer); + * } else if (key.equals(MY_BACKUP_KEY_TO_IGNORE) { + * // a key we recognize but wish to discard + * data.skipEntityData(); + * } // ... etc. + * }</pre> */ public class BackupDataInput { int mBackupReader; @@ -52,10 +86,12 @@ public class BackupDataInput { } /** - * Consumes the next header from the restore stream. + * Extract the next entity header from the restore stream. After this method + * return success, the {@link #getKey()} and {@link #getDataSize()} methods can + * be used to inspect the entity that is now available for processing. * - * @return true when there is an entity ready for consumption from the restore stream, - * false if the restore stream has been fully consumed. + * @return <code>true</code> when there is an entity ready for consumption from the + * restore stream, <code>false</code> if the restore stream has been fully consumed. * @throws IOException if an error occurred while reading the restore stream */ public boolean readNextHeader() throws IOException { @@ -71,25 +107,25 @@ public class BackupDataInput { } else { // error mHeaderReady = false; - throw new IOException("result=0x" + Integer.toHexString(result)); + throw new IOException("failed: 0x" + Integer.toHexString(result)); } } /** - * Report the key associated with the current record in the restore stream - * @return the current record's key string + * Report the key associated with the current entity in the restore stream + * @return the current entity's key string * @throws IllegalStateException if the next record header has not yet been read */ public String getKey() { if (mHeaderReady) { return mHeader.key; } else { - throw new IllegalStateException("mHeaderReady=false"); + throw new IllegalStateException("Entity header not read"); } } /** - * Report the size in bytes of the data associated with the current record in the + * Report the size in bytes of the data associated with the current entity in the * restore stream. * * @return The size of the record's raw data, in bytes @@ -99,7 +135,7 @@ public class BackupDataInput { if (mHeaderReady) { return mHeader.dataSize; } else { - throw new IllegalStateException("mHeaderReady=false"); + throw new IllegalStateException("Entity header not read"); } } @@ -107,13 +143,15 @@ public class BackupDataInput { * Read a record's raw data from the restore stream. The record's header must first * have been processed by the {@link #readNextHeader()} method. Multiple calls to * this method may be made in order to process the data in chunks; not all of it - * must be read in a single call. + * must be read in a single call. Once all of the raw data for the current entity + * has been read, further calls to this method will simply return zero. * * @param data An allocated byte array of at least 'size' bytes * @param offset Offset within the 'data' array at which the data will be placed - * when read from the stream. - * @param size The number of bytes to read in this pass. - * @return The number of bytes of data read + * when read from the stream + * @param size The number of bytes to read in this pass + * @return The number of bytes of data read. Once all of the data for this entity + * has been read, further calls to this method will return zero. * @throws IOException if an error occurred when trying to read the restore data stream */ public int readEntityData(byte[] data, int offset, int size) throws IOException { @@ -125,12 +163,12 @@ public class BackupDataInput { throw new IOException("result=0x" + Integer.toHexString(result)); } } else { - throw new IllegalStateException("mHeaderReady=false"); + throw new IllegalStateException("Entity header not read"); } } /** - * Consume the current record's data without actually reading it into a buffer + * Consume the current entity's data without extracting it into a buffer * for further processing. This allows a {@link android.app.backup.BackupAgent} to * efficiently discard obsolete or otherwise uninteresting records during the * restore operation. @@ -141,7 +179,7 @@ public class BackupDataInput { if (mHeaderReady) { skipEntityData_native(mBackupReader); } else { - throw new IllegalStateException("mHeaderReady=false"); + throw new IllegalStateException("Entity header not read"); } } diff --git a/core/java/android/app/backup/BackupDataOutput.java b/core/java/android/app/backup/BackupDataOutput.java index 3767797..a69547a 100644 --- a/core/java/android/app/backup/BackupDataOutput.java +++ b/core/java/android/app/backup/BackupDataOutput.java @@ -16,11 +16,49 @@ package android.app.backup; +import android.os.ParcelFileDescriptor; + import java.io.FileDescriptor; import java.io.IOException; /** - * STOPSHIP: document + * This class is the structured conduit through which a {@link BackupAgent} commits + * information to the current backup data set. Data written for backup is presented + * as a set of "entities," key/value pairs in which each binary data record "value" is + * named with a string "key." + * <p> + * To commit a data record to the backup transport, the agent's + * {@link BackupAgent#onBackup(android.os.ParcelFileDescriptor, BackupDataOutput, android.os.ParcelFileDescriptor)} + * method first writes an "entity header" that supplies the key string for the record + * and the total size of the binary value for the record. After the header has been + * written the agent then writes the binary entity value itself. The entity value can + * be written in multiple chunks if desired, as long as the total count of bytes written + * matches what was supplied to {@link #writeEntityHeader(String, int)}. + * <p> + * Entity key strings are considered to be unique within a given application's backup + * data set. If a new entity is written under an existing key string, its value will + * replace any previous value in the transport's remote data store. A record can be + * removed entirely from the remote data set by writing a new entity header using the + * existing record's key, but supplying a negative <code>dataSize</code> parameter. + * When doing this the agent does not need to call {@link #writeEntityData(byte[], int)}. + * <p> + * <b>Example</b> + * <p> + * Here is an example illustrating a way to back up the value of a String variable + * called <code>mStringToBackUp</code>: + * <pre> + * static final String MY_STRING_KEY = "storedstring"; + * + * public void {@link BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor) onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState)} + * throws IOException { + * ... + * byte[] stringBytes = mStringToBackUp.getBytes(); + * data.writeEntityHeader(MY_STRING_KEY, stringBytes.length); + * data.writeEntityData(stringBytes, stringBytes.length); + * ... + * }</pre> + * + * @see BackupAgent */ public class BackupDataOutput { int mBackupWriter; diff --git a/core/java/android/app/backup/BackupHelper.java b/core/java/android/app/backup/BackupHelper.java index b7ef268..3f41ed2 100644 --- a/core/java/android/app/backup/BackupHelper.java +++ b/core/java/android/app/backup/BackupHelper.java @@ -20,10 +20,10 @@ import android.os.ParcelFileDescriptor; /** * A convenient interface to be used with the - * {@link android.app.backup.BackupAgentHelper} to implement backup and restore of + * {@link android.app.backup.BackupAgentHelper} class to implement backup and restore of * arbitrary data types. * <p> - * STOPSHOP: document! + * STOPSHIP: document! */ public interface BackupHelper { /** @@ -46,9 +46,8 @@ public interface BackupHelper { /** * Called by {@link android.app.backup.BackupAgentHelper BackupAgentHelper} - * to write the new backup state file corresponding to - * the current state of the app's data at the time the backup operation was - * performed. + * after a restore operation to write the backup state file corresponding to + * the data as processed by the helper. */ public void writeNewStateDescription(ParcelFileDescriptor fd); } diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java index 7eb6265..7070827 100644 --- a/core/java/android/app/backup/BackupManager.java +++ b/core/java/android/app/backup/BackupManager.java @@ -25,9 +25,9 @@ import android.os.ServiceManager; import android.util.Log; /** - * BackupManager is the interface to the system's backup service. Applications - * simply instantiate one, and then use that instance to communicate with the - * backup infrastructure. + * The BackupManager class is interface through which an application's user interface + * code will interact with the Android backup service. Applications simply instantiate one + * and then issue calls through that instance. * <p> * When an application has made changes to data which should be backed up, a * call to {@link #dataChanged()} will notify the backup service. The system @@ -35,24 +35,23 @@ import android.util.Log; * calls to {@link #dataChanged()} have no further effect until the backup * operation actually occurs. * <p> - * The backup operation itself begins with the system launching the + * A backup or restore operation begins with the system launching the * {@link android.app.backup.BackupAgent} subclass declared in your manifest. See the * documentation for {@link android.app.backup.BackupAgent} for a detailed description - * of how the backup then proceeds. - * <p> - * A simple implementation of a BackupAgent useful for backing up Preferences - * and files is available by using {@link android.app.backup.BackupAgentHelper}. - * <p> - * STOPSHIP: more documentation! + * of how the operation then proceeds. * <p> * <b>XML attributes</b> * <p> - * See {@link android.R.styleable#AndroidManifestApplication - * AndroidManifest.xml's application attributes} + * Several attributes affecting the operation of the backup and restore mechanism + * can be set on the <application> tag in the application's + * AndroidManifest.xml file. See the documentation on the + * {@link android.R.styleable#AndroidManifestApplication AndroidManifest.xml's application attributes} + * for details. * * @attr ref android.R.styleable#AndroidManifestApplication_allowBackup * @attr ref android.R.styleable#AndroidManifestApplication_backupAgent * @attr ref android.R.styleable#AndroidManifestApplication_killAfterRestore + * @attr ref android.R.styleable#AndroidManifestApplication_restoreAnyVersion */ public class BackupManager { private static final String TAG = "BackupManager"; @@ -82,7 +81,8 @@ public class BackupManager { /** * Notifies the Android backup system that your application wishes to back up * new changes to its data. A backup operation using your application's - * {@link android.app.backup.BackupAgent} subclass will be scheduled when you call this method. + * {@link android.app.backup.BackupAgent} subclass will be scheduled when you + * call this method. */ public void dataChanged() { checkServiceBinder(); @@ -97,11 +97,12 @@ public class BackupManager { /** * Convenience method for callers who need to indicate that some other package - * needs a backup pass. This can be relevant in the case of groups of packages - * that share a uid, for example. - * + * needs a backup pass. This can be useful in the case of groups of packages + * that share a uid. + * <p> * This method requires that the application hold the "android.permission.BACKUP" - * permission if the package named in the argument is not the caller's own. + * permission if the package named in the argument does not run under the same uid + * as the caller. */ public static void dataChanged(String packageName) { checkServiceBinder(); diff --git a/core/java/android/app/backup/FileBackupHelper.java b/core/java/android/app/backup/FileBackupHelper.java index 3ce5b43..a326941 100644 --- a/core/java/android/app/backup/FileBackupHelper.java +++ b/core/java/android/app/backup/FileBackupHelper.java @@ -26,18 +26,13 @@ import java.io.File; * A helper class which can be used in conjunction with * {@link android.app.backup.BackupAgentHelper} to manage the backup of a set of * files. Whenever backup is performed, all files changed since the last backup - * will be saved in their entirety. During the first time the backup happens, - * all the files in the list will be backed up. Note that this should only be - * used with small configuration files and not with large binary files. + * will be saved in their entirety. During the first time the backup happens, + * every file in the list will be backed up. Note that this should only be + * used with small configuration files, not with large binary files. * <p> - * Any files not present in the list of files during the restore procedure will - * be ignored. If files present in a previous version of an application are - * removed in subsequent versions, it is the responsibility of the developer to - * design a mechanism to remove those files. Otherwise files no longer needed - * will linger and consume space on the device. - * <p> - * STOPSHIP: document! [manages backup of a set of files; restore is totally - * opaque] + * During restore, if the helper encounters data for a file that was not + * specified when the FileBackupHelper object was constructed, that data + * will be ignored. */ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "FileBackupHelper"; @@ -69,8 +64,8 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp * now. When <code>oldState</code> is <code>null</code>, all the files will * be backed up. * <p> - * This should be called from {@link android.app.backup.BackupAgentHelper} - * directly. See + * This should only be called directly from within the {@link BackupAgentHelper} + * implementation. See * {@link android.app.backup.BackupAgent#onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)} * for a description of parameter meanings. */ @@ -91,6 +86,9 @@ public class FileBackupHelper extends FileBackupHelperBase implements BackupHelp /** * Restore one record [representing a single file] from the restore dataset. + * <p> + * This should only be called directly from within the {@link BackupAgentHelper} + * implementation. */ public void restoreEntity(BackupDataInputStream data) { if (DEBUG) Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); diff --git a/core/java/android/app/backup/SharedPreferencesBackupHelper.java b/core/java/android/app/backup/SharedPreferencesBackupHelper.java index f9e6b28..9efecc5 100644 --- a/core/java/android/app/backup/SharedPreferencesBackupHelper.java +++ b/core/java/android/app/backup/SharedPreferencesBackupHelper.java @@ -26,11 +26,45 @@ import java.io.File; /** * A helper class which can be used in conjunction with * {@link android.app.backup.BackupAgentHelper} to manage the backup of - * {@link android.content.SharedPreferences}. Whenever backup is performed it + * {@link android.content.SharedPreferences}. Whenever a backup is performed it * will back up all named shared preferences which have changed since the last - * backup. + * backup operation. * <p> - * STOPSHIP: document! + * To use this class, the application's agent class should extend + * {@link android.app.backup.BackupAgentHelper}. Then, in the agent's + * {@link BackupAgent#onCreate()} method, an instance of this class should be + * allocated and installed as a backup/restore handler within the BackupAgentHelper + * framework. An implementation of an agent supporting backup and restore for + * an application that wishes to back up two groups of {@link android.content.SharedPreferences} + * data might look something like this: + * <pre> + * import android.app.backup.BackupAgentHelper; + * import android.app.backup.SharedPreferencesBackupHelper; + * + * public class MyBackupAgent extends BackupAgentHelper { + * // The names of the SharedPreferences groups that the application maintains. These + * // are the same strings that are passed to {@link Context#getSharedPreferences(String, int)}. + * static final String PREFS_DISPLAY = "displayprefs"; + * static final String PREFS_SCORES = "highscores"; + * + * // An arbitrary string used within the BackupAgentHelper implementation to + * // identify the SharedPreferenceBackupHelper's data. + * static final String MY_PREFS_BACKUP_KEY = "myprefs"; + * + * // Simply allocate a helper and install it + * void onCreate() { + * SharedPreferencesBackupHelper helper = + * new SharedPreferencesBackupHelper(this, PREFS_DISPLAY, PREFS_SCORES); + * addHelper(MY_PREFS_BACKUP_KEY, helper); + * } + * }</pre> + * <p> + * No further implementation is needed; the BackupAgentHelper mechanism automatically + * dispatches the + * {@link BackupAgent#onBackup(android.os.ParcelFileDescriptor, BackupDataOutput, android.os.ParcelFileDescriptor) BackupAgent.onBackup()} + * and + * {@link BackupAgent#onRestore(BackupDataInput, int, android.os.ParcelFileDescriptor) BackupAgent.onRestore()} + * callbacks to the SharedPreferencesBackupHelper as appropriate. */ public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "SharedPreferencesBackupHelper"; diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 65ec2f7..e8df2b6 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -591,8 +591,8 @@ <!-- Application's requirement for five way navigation --> <attr name="reqFiveWayNav" format="boolean" /> - <!-- The name of the class implementing <code>BackupAgent</code> to manage - backup and restore of application data on external storage. --> + <!-- The name of the class subclassing <code>BackupAgent</code> to manage + backup and restore of the application's data on external storage. --> <attr name="backupAgent" format="string" /> <!-- Whether to allow the application to participate in backup diff --git a/docs/html/guide/topics/manifest/application-element.jd b/docs/html/guide/topics/manifest/application-element.jd index 5b3fcd5..08f35e9 100644 --- a/docs/html/guide/topics/manifest/application-element.jd +++ b/docs/html/guide/topics/manifest/application-element.jd @@ -3,19 +3,23 @@ page.title=<application> <dl class="xml"> <dt>syntax:</dt> -<dd><pre class="stx"><application android:<a href="#clear">allowClearUserData</a>=["true" | "false"] +<dd><pre class="stx"><application android:<a href="#backup">allowBackup</a>=["true" | "false"] + android:<a href="#clear">allowClearUserData</a>=["true" | "false"] android:<a href="#reparent">allowTaskReparenting</a>=["true" | "false"] + android:<a href="#agent">backupAgent</a>="<i>string</i>" android:<a href="#debug">debuggable</a>=["true" | "false"] android:<a href="#desc">description</a>="<i>string resource</i>" android:<a href="#enabled">enabled</a>=["true" | "false"] android:<a href="#code">hasCode</a>=["true" | "false"] android:<a href="#icon">icon</a>="<i>drawable resource</i>" + android:<a href="#killrst">killAfterRestore</a>=["true" | "false"] android:<a href="#label">label</a>="<i>string resource</i>" android:<a href="#space">manageSpaceActivity</a>="<i>string</i>" android:<a href="#nm">name</a>="<i>string</i>" android:<a href="#prmsn">permission</a>="<i>string</i>" android:<a href="#persistent">persistent</a>=["true" | "false"] android:<a href="#proc">process</a>="<i>string</i>" + android:<a href="#restoreany">restoreAnyVersion</a>=["true" | "false"] android:<a href="#aff">taskAffinity</a>="<i>string</i>" android:<a href="#theme">theme</a>="<i>resource or theme</i>" > . . . @@ -45,6 +49,16 @@ cannot be overridden by the components.</dd> <dt>attributes</dt> <dd><dl class="attr"> +<dt><a name="backup"></a>{@code android:allowBackup}</dt> +<dd>Whether the application allows its data to be backed up through the Android +Backup Manager — "{@code true}" if it does, "{@code false}" if not. By +default this attribute is "{@code true}". If an application declares this +attribute to be "{@code false}" the Backup Manager will never attempt to +perform any backup or restore operation, even if the application declares a +valid <a href="#agent">{@code android:backupAgent}</a> attribute in its +manifest. +</dd> + <dt><a name="clear"></a>{@code android:allowClearUserData}</dt> <dd>Whether or not users are given the option to remove user data — "{@code true}" if they are, and "{@code false}" if not. If the value is @@ -67,6 +81,20 @@ attribute that can override the value set here. See that attribute for more information. </p></dd> +<dt><a name="agent"></a>{@code android:backupAgent}</dt> +<dd>The name of the class that implement's the application's backup agent, +a subclass of {@link android.app.backup.BackupAgent}. The attribute value should be +a fully qualified class name (such as, "{@code com.example.project.MyBackupAgent}"). +However, as a shorthand, if the first character of the name is a period +(for example, "{@code .MyBackupAgent}"), it is appended to the +package name specified in the +<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> +element. + +<p> +There is no default. The name must be specified. +</p></dd> + <dt><a name="debug"></a>{@code android:debuggable}</dt> <dd>Whether or not the application can be debugged, even when running on a device in user mode — "{@code true}" if it can be, and "{@code false}" @@ -113,6 +141,19 @@ This attribute must be set as a reference to a drawable resource containing the image definition. There is no default icon. </p></dd> +<dt><a name="killrst"></a>{@code android:killAfterRestore}</dt> +<dd>Whether the application in question should be terminated after its +settings have been restored during a full-system restore operation. +Single-package restore operations will never cause the application to +be shut down. Full-system restore operations typically only occur once, +when the phone is first set up. Third-party applications will not normally +need to use this attribute. + +<p>The default is {@code true}, which means that after the application +has finished processing its data during a full-system restore, it will be +terminated. +</p></dd> + <dt><a name="label"></a>{@code android:label}</dt> <dd>A user-readable label for the application as a whole, and a default label for each of the application's components. See the individual @@ -196,6 +237,17 @@ of that name is created. A global process can be shared with other applications, reducing resource usage. </p></dd> +<dt><a href name="restoreany"></a>{@code android:restoreAnyVersion}</dt> +<dd>Indicate that the application is prepared to attempt a restore of any +backed-up data set, even if the backup was stored by a newer version +of the application than is currently installed on the device. Setting +this attribute to {@code true} will permit the Backup Manager to +attempt restore even when a version mismatch suggests that the data are +incompatible. <em>Use with caution!</em> + +<p>The default value of this attribute is {@code false}. +</p></dd> + <dt><a href name="aff"></a>{@code android:taskAffinity}</dt> <dd>An affinity name that applies to all activities within the application, except for those that set a different affinity with their own |