سرویس پشتیبانگیری Android، پشتیبانگیری و بازیابی دادههای کلید-مقدار را در برنامه Android شما فراهم میکند. در طول عملیات پشتیبانگیری کلید-مقدار، دادههای پشتیبان برنامه به انتقال پشتیبان دستگاه ارسال میشود. اگر دستگاه از انتقال پیشفرض پشتیبان Google استفاده میکند، دادهها برای بایگانی به سرویس پشتیبانگیری Android منتقل میشوند.
داده ها به 5 مگابایت برای هر کاربر برنامه شما محدود است. هیچ هزینه ای برای ذخیره سازی داده های پشتیبان دریافت نمی شود.
برای مروری بر گزینههای پشتیبانگیری Android و راهنمایی در مورد اینکه کدام دادهها را باید پشتیبان بگیرید و بازیابی کنید، به نمای کلی پشتیبانگیری از دادهها مراجعه کنید.
اجرای پشتیبان کلید-مقدار
برای پشتیبان گیری از داده های برنامه خود، باید یک عامل پشتیبان پیاده سازی کنید. عامل پشتیبان شما در حین پشتیبان گیری و بازیابی توسط مدیر پشتیبان گیری فراخوانی می شود.
برای پیاده سازی یک عامل پشتیبان، باید:
عامل پشتیبان خود را در فایل مانیفست خود با ویژگی
android:backupAgent
اعلام کنید.با انجام یکی از موارد زیر یک عامل پشتیبان تعریف کنید:
کلاس
BackupAgent
رابط مرکزی را ارائه می دهد که برنامه شما از آن برای ارتباط با مدیر پشتیبان استفاده می کند. اگر مستقیماً این کلاس را گسترش دهید، بایدonBackup()
وonRestore()
را لغو کنید تا عملیات پشتیبان گیری و بازیابی داده های شما انجام شود.کلاس
BackupAgentHelper
یک بسته بندی مناسب در اطراف کلاسBackupAgent
فراهم می کند که مقدار کد مورد نیاز برای نوشتن را به حداقل می رساند. درBackupAgentHelper
خود، باید از یک یا چند شیء کمکی استفاده کنید که به طور خودکار از انواع خاصی از داده ها نسخه پشتیبان تهیه و بازیابی می کنند، به طوری که نیازی به پیاده سازیonBackup()
وonRestore()
ندارید. توصیه میکنیم ازBackupAgentHelper
برای مدیریت پشتیبانگیریهای برنامه خود استفاده کنید، مگر اینکه نیاز به کنترل کامل بر روی پشتیبانگیری برنامه خود داشته باشید.Android در حال حاضر کمکهایی برای پشتیبانگیری ارائه میکند که فایلهای کامل را از
SharedPreferences
و حافظه داخلی پشتیبانگیری و بازیابی میکنند.
عامل پشتیبان را در مانیفست خود اعلام کنید
هنگامی که نام کلاس عامل پشتیبان خود را انتخاب کردید، آن را در مانیفست خود با استفاده از ویژگی android:backupAgent
در تگ <application>
اعلام کنید.
به عنوان مثال:
<manifest ... > ... <application android:label="MyApplication" android:backupAgent="MyBackupAgent"> <meta-data android:name="com.google.android.backup.api_key" android:value="unused" /> <activity ... > ... </activity> </application> </manifest>
برای پشتیبانی از دستگاههای قدیمیتر، توصیه میکنیم کلید API <meta-data>
را به فایل مانیفست اندروید خود اضافه کنید. سرویس پشتیبانگیری Android دیگر به کلید سرویس نیاز ندارد، اما برخی از دستگاههای قدیمیتر ممکن است همچنان هنگام پشتیبانگیری، کلیدی را بررسی کنند. android:name
را روی com.google.android.backup.api_key
و android:value
را روی unused
تنظیم کنید.
ویژگی android:restoreAnyVersion
یک مقدار بولی دریافت می کند تا نشان دهد که آیا می خواهید داده های برنامه را بدون توجه به نسخه فعلی برنامه در مقایسه با نسخه ای که داده های پشتیبان تهیه کرده است بازیابی کنید یا خیر. مقدار پیش فرض false
است. برای اطلاعات بیشتر به بررسی نسخه بازیابی داده مراجعه کنید.
BackupAgentHelper را گسترش دهید
اگر میخواهید از فایلهای کامل از SharedPreferences
یا حافظه داخلی نسخه پشتیبان تهیه کنید، باید عامل پشتیبان خود را با استفاده از BackupAgentHelper
بسازید. ساخت عامل پشتیبان خود با BackupAgentHelper
به کد بسیار کمتری نسبت به گسترش BackupAgent
نیاز دارد، زیرا نیازی به پیاده سازی onBackup()
و onRestore()
ندارید.
اجرای BackupAgentHelper
شما باید از یک یا چند کمک پشتیبان استفاده کند. کمک پشتیبان یک جزء تخصصی است که BackupAgentHelper
برای انجام عملیات پشتیبان گیری و بازیابی برای یک نوع خاص از داده ها احضار می کند. فریم ورک اندروید در حال حاضر دو کمک کننده مختلف ارائه می دهد:
-
SharedPreferencesBackupHelper
برای پشتیبانگیری از فایلهایSharedPreferences
. -
FileBackupHelper
برای پشتیبان گیری از فایل ها از حافظه داخلی.
می توانید چندین کمک کننده را در BackupAgentHelper
خود بگنجانید، اما برای هر نوع داده فقط یک کمک کننده مورد نیاز است. یعنی اگر چندین فایل SharedPreferences
دارید، تنها به یک SharedPreferencesBackupHelper
نیاز دارید.
برای هر کمکی که می خواهید به BackupAgentHelper
خود اضافه کنید، باید در طول متد onCreate()
خود این کار را انجام دهید:
- نمونه ای از کلاس کمکی مورد نظر را نمونه سازی کنید. در سازنده کلاس، باید فایل(هایی) را که می خواهید پشتیبان بگیرید مشخص کنید.
- برای افزودن کمک کننده به
BackupAgentHelper
خودaddHelper()
فراخوانی کنید.
بخش های زیر نحوه ایجاد یک عامل پشتیبان با استفاده از هر یک از کمک های موجود را شرح می دهد.
از SharedPreferences نسخه پشتیبان تهیه کنید
وقتی یک SharedPreferencesBackupHelper
نمونهسازی میکنید، باید نام یک یا چند فایل SharedPreferences
را وارد کنید.
به عنوان مثال، برای پشتیبان گیری از یک فایل SharedPreferences
با نام user_preferences
، یک عامل پشتیبان کامل با استفاده از BackupAgentHelper
به شکل زیر است:
کاتلین
// The name of the SharedPreferences file const val PREFS = "user_preferences" // A key to uniquely identify the set of backup data const val PREFS_BACKUP_KEY = "prefs" class MyPrefsBackupAgent : BackupAgentHelper() { override fun onCreate() { // Allocate a helper and add it to the backup agent SharedPreferencesBackupHelper(this, PREFS).also { addHelper(PREFS_BACKUP_KEY, it) } } }
جاوا
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); } }
SharedPreferencesBackupHelper
شامل تمام کدهای مورد نیاز برای پشتیبان گیری و بازیابی فایل SharedPreferences
است.
هنگامی که مدیر پشتیبان گیری onBackup()
و onRestore()
فرا می خواند، BackupAgentHelper
از کمک کنندگان پشتیبان شما برای تهیه نسخه پشتیبان و بازیابی فایل های مشخص شده شما فراخوانی می کند.
از سایر فایل ها بک آپ بگیرید
هنگامی که یک FileBackupHelper
نمونهسازی میکنید، باید نام یک یا چند فایل را که در حافظه داخلی برنامه شما ذخیره شدهاند، درج کنید، همانطور که توسط getFilesDir()
مشخص شده است، که همان مکانی است که openFileOutput()
فایلها را مینویسد.
به عنوان مثال، برای تهیه نسخه پشتیبان از دو فایل به نام scores
و stats
، یک عامل پشتیبان با استفاده از BackupAgentHelper
به شکل زیر است:
کاتلین
// The name of the file const val TOP_SCORES = "scores" const val PLAYER_STATS = "stats" // A key to uniquely identify the set of backup data const val FILES_BACKUP_KEY = "myfiles" class MyFileBackupAgent : BackupAgentHelper() { override fun onCreate() { // Allocate a helper and add it to the backup agent FileBackupHelper(this, TOP_SCORES, PLAYER_STATS).also { addHelper(FILES_BACKUP_KEY, it) } } }
جاوا
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); } }
FileBackupHelper
شامل تمام کدهای لازم برای پشتیبان گیری و بازیابی فایل هایی است که در حافظه داخلی برنامه شما ذخیره شده اند.
با این حال، خواندن و نوشتن روی فایلها در حافظه داخلی امن نیست . برای اطمینان از اینکه عامل پشتیبان شما همزمان با فعالیت های شما فایل های شما را نمی خواند یا نمی نویسد، باید هر بار که خواندن یا نوشتن را انجام می دهید از عبارات همگام سازی شده استفاده کنید. به عنوان مثال، در هر فعالیتی که فایل را می خوانید و می نویسید، به یک شی نیاز دارید که به عنوان قفل ذاتی برای عبارات همگام سازی شده استفاده کنید:
کاتلین
// Object for intrinsic lock companion object { val sDataLock = Any() }
جاوا
// Object for intrinsic lock static final Object sDataLock = new Object();
سپس هر بار که فایل ها را می خوانید یا می نویسید، یک عبارت همگام سازی شده با این قفل ایجاد کنید. برای مثال، در اینجا یک عبارت هماهنگ برای نوشتن آخرین امتیاز یک بازی در یک فایل آمده است:
کاتلین
try { synchronized(MyActivity.sDataLock) { val dataFile = File(filesDir, TOP_SCORES) RandomAccessFile(dataFile, "rw").apply { writeInt(score) } } } catch (e: IOException) { Log.e(TAG, "Unable to write to file") }
جاوا
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"); }
شما باید عبارات خوانده شده خود را با همان قفل همگام کنید.
سپس، در BackupAgentHelper
خود، باید onBackup()
و onRestore()
لغو کنید تا عملیات پشتیبان گیری و بازیابی با همان قفل ذاتی همگام سازی شود. به عنوان مثال، مثال MyFileBackupAgent
از بالا به روش های زیر نیاز دارد:
کاتلین
@Throws(IOException::class) override fun onBackup( oldState: ParcelFileDescriptor, data: BackupDataOutput, newState: ParcelFileDescriptor ) { // Hold the lock while the FileBackupHelper performs back up synchronized(MyActivity.sDataLock) { super.onBackup(oldState, data, newState) } } @Throws(IOException::class) override fun onRestore( data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor ) { // Hold the lock while the FileBackupHelper restores the file synchronized(MyActivity.sDataLock) { super.onRestore(data, appVersionCode, newState) } }
جاوا
@Override public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { // Hold the lock while the FileBackupHelper performs back up 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); } }
BackupAgent را گسترش دهید
اکثر برنامه ها نیازی به گسترش مستقیم کلاس BackupAgent
ندارند، بلکه باید BackupAgentHelper
گسترش دهند تا از کلاس های کمکی داخلی که به طور خودکار از فایل های شما نسخه پشتیبان تهیه و بازیابی می کنند، استفاده کنند. با این حال، می توانید BackupAgent
مستقیماً برای انجام کارهای زیر گسترش دهید:
- فرمت داده خود را نسخه کنید. به عنوان مثال، اگر پیشبینی میکنید که باید در قالبی که دادههای برنامه خود را در آن مینویسید تجدیدنظر کنید، میتوانید یک عامل پشتیبان بسازید تا نسخه برنامه شما را در طول عملیات بازیابی متقاطع بررسی کند و اگر نسخه موجود در دستگاه باشد، هرگونه کار سازگاری لازم را انجام دهید. متفاوت از داده های پشتیبان. برای اطلاعات بیشتر، به بررسی نسخه بازیابی داده مراجعه کنید.
- قسمت هایی از داده ها را برای پشتیبان گیری مشخص کنید. به جای پشتیبانگیری از کل فایل، میتوانید بخشهایی از دادهها را برای پشتیبانگیری و نحوه بازیابی هر بخش به دستگاه را مشخص کنید. این همچنین میتواند به شما در مدیریت نسخههای مختلف کمک کند، زیرا دادههای خود را بهجای فایلهای کامل میخوانید و مینویسید.
- پشتیبان گیری از داده ها در پایگاه داده اگر یک پایگاه داده SQLite دارید که میخواهید زمانی که کاربر برنامه شما را دوباره نصب میکند، آن را بازیابی کنید، باید یک
BackupAgent
سفارشی بسازید که دادههای مناسب را در طول عملیات پشتیبانگیری بخواند، سپس جدول خود را ایجاد کنید و دادهها را در طول عملیات بازیابی وارد کنید.
اگر نیازی به انجام هیچ یک از وظایف بالا ندارید و میخواهید از فایلهای کامل از SharedPreferences
یا حافظه داخلی نسخه پشتیبان تهیه کنید، به گسترش BackupAgentHelper
مراجعه کنید.
روش های مورد نیاز
وقتی یک BackupAgent
ایجاد میکنید، باید روشهای برگشت تماس زیر را پیادهسازی کنید:
-
onBackup()
- پس از درخواست پشتیبان، مدیر پشتیبان گیری این روش را فراخوانی می کند. در این روش، دادههای برنامه خود را از دستگاه میخوانید و دادههایی را که میخواهید از آن نسخه پشتیبان تهیه کنید، به مدیر پشتیبانگیری ارسال میکنید، همانطور که در انجام یک نسخه پشتیبان توضیح داده شده است.
-
onRestore()
مدیر پشتیبان گیری این روش را در طول عملیات بازیابی فراخوانی می کند. این روش دادههای پشتیبان شما را ارائه میکند، که برنامه شما میتواند از آن برای بازیابی حالت قبلی خود استفاده کند، همانطور که در انجام بازیابی توضیح داده شده است.
هنگامی که کاربر برنامه شما را دوباره نصب می کند، سیستم این روش را برای بازیابی اطلاعات پشتیبان می نامد، اما برنامه شما همچنین می تواند درخواست بازیابی کند .
پشتیبان گیری انجام دهید
درخواست پشتیبانگیری منجر به فراخوانی فوری روش onBackup()
شما نمیشود. در عوض، مدیر پشتیبان گیری برای زمان مناسب منتظر می ماند، سپس برای همه برنامه هایی که از آخرین نسخه پشتیبان درخواست کرده اند یک نسخه پشتیبان تهیه می کند. این نقطه ای است که باید داده های برنامه خود را در اختیار مدیر پشتیبان گیری قرار دهید تا بتوان آن را در فضای ذخیره سازی ابری ذخیره کرد.
فقط مدیر پشتیبان می تواند متد onBackup()
عامل پشتیبان شما را فراخوانی کند. هر بار که داده های برنامه شما تغییر می کند و می خواهید یک نسخه پشتیبان انجام دهید، باید با فراخوانی dataChanged()
درخواست یک عملیات پشتیبان گیری کنید. برای اطلاعات بیشتر به درخواست پشتیبان مراجعه کنید.
نکته : هنگام توسعه برنامه خود، می توانید یک عملیات پشتیبان گیری فوری از مدیر پشتیبان گیری با ابزار bmgr
را آغاز کنید.
هنگامی که مدیر پشتیبان گیری متد onBackup()
شما را فراخوانی می کند، سه پارامتر را ارسال می کند:
-
oldState
- یک
ParcelFileDescriptor
باز و فقط خواندنی که به آخرین وضعیت پشتیبان ارائه شده توسط برنامه شما اشاره می کند. این دادههای پشتیبانگیری از فضای ذخیرهسازی ابری نیست، بلکه یک نمایش محلی از دادههایی است که آخرین باری کهonBackup()
پشتیبان گرفته شده است، همانطور که توسطnewState
یا ازonRestore()
تعریف شده است.onRestore()
در بخش بعدی پوشش داده شده است. از آنجایی کهonBackup()
به شما اجازه نمیدهد دادههای پشتیبان موجود در فضای ذخیرهسازی ابری را بخوانید، میتوانید از این نمایش محلی برای تعیین اینکه آیا دادههای شما از آخرین نسخه پشتیبان تغییر کرده است یا خیر استفاده کنید. -
data
- یک شی
BackupDataOutput
که از آن برای تحویل داده های پشتیبان خود به مدیر پشتیبان استفاده می کنید. -
newState
- یک
ParcelFileDescriptor
باز، خواندن/نوشتن که به فایلی اشاره میکند که در آن باید نمایشی از دادههایی که بهdata
تحویل دادهاید بنویسید. یک نمایش می تواند به سادگی آخرین مُهر زمانی اصلاح شده برای فایل شما باشد. دفعه بعد که مدیر پشتیبان گیری متدonBackup()
شما را فراخوانی کرد، این شی به عنوانoldState
برگردانده می شود. اگر اطلاعات پشتیبان خود را درnewState
ننویسید، دفعه بعد که Backup ManageronBackup()
را فراخواندoldState
به یک فایل خالی اشاره می کند.
با استفاده از این پارامترها، متد onBackup()
خود را برای انجام موارد زیر پیاده سازی کنید:
با مقایسه
oldState
با داده های فعلی خود بررسی کنید که آیا داده های شما از آخرین نسخه پشتیبان تغییر کرده است یا خیر. نحوه خواندن داده ها درoldState
بستگی به نحوه نوشتن آن درnewState
دارد (مرحله 3 را ببینید). ساده ترین راه برای ثبت وضعیت یک فایل، آخرین بار اصلاح شده آن است. برای مثال، در اینجا نحوه خواندن و مقایسه مهر زمانی ازoldState
آمده است:کاتلین
val instream = FileInputStream(oldState.fileDescriptor) val dataInputStream = DataInputStream(instream) try { // Get the last modified timestamp from the state file and data file val stateModified = dataInputStream.readLong() val fileModified: Long = dataFile.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 (e: IOException) { // Unable to read state file... be safe and do a backup }
جاوا
// 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 = dataFile.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 }
اگر چیزی تغییر نکرده است و نیازی به پشتیبان گیری ندارید، به مرحله 3 بروید.
اگر دادههای شما در مقایسه با
oldState
تغییر کرده است، دادههای فعلی را رویdata
بنویسید تا از آنها در فضای ذخیرهسازی ابری نسخه پشتیبان تهیه کنید.شما باید هر تکه داده را به عنوان یک موجودیت در
BackupDataOutput
بنویسید. یک موجودیت یک رکورد داده باینری مسطح است که توسط یک رشته کلید منحصر به فرد شناسایی می شود. بنابراین، مجموعه داده ای که از آن نسخه پشتیبان تهیه می کنید، از نظر مفهومی مجموعه ای از جفت های کلید-مقدار است.برای افزودن یک موجودیت به مجموعه داده های پشتیبان خود، باید:
writeEntityHeader()
را فراخوانی کنید و یک کلید رشته ای منحصر به فرد برای داده هایی که می خواهید بنویسید و اندازه داده ارسال کنید.writeEntityData()
را فراخوانی کنید و یک بافر بایتی را ارسال کنید که حاوی داده های شما و تعداد بایت هایی است که باید از بافر بنویسید، که باید با اندازه ارسال شده بهwriteEntityHeader()
مطابقت داشته باشد.
به عنوان مثال، کد زیر برخی از داده ها را در یک جریان بایت مسطح می کند و آن را در یک موجودیت واحد می نویسد:
کاتلین
val buffer: ByteArray = ByteArrayOutputStream().run { DataOutputStream(this).apply { writeInt(playerName) writeInt(playerScore) } toByteArray() } val len: Int = buffer.size data.apply { writeEntityHeader(TOPSCORE_BACKUP_KEY, len) writeEntityData(buffer, len) }
جاوا
// Create buffer stream and data output stream for our data ByteArrayOutputStream bufStream = new ByteArrayOutputStream(); DataOutputStream outWriter = new DataOutputStream(bufStream); // Write structured data outWriter.writeUTF(playerName); outWriter.writeInt(playerScore); // 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);
این کار را برای هر قطعه داده ای که می خواهید پشتیبان بگیرید انجام دهید. اینکه چگونه داده های خود را به موجودیت ها تقسیم می کنید به شما بستگی دارد. حتی ممکن است فقط از یک موجودیت استفاده کنید.
چه پشتیبانگیری انجام دهید یا نه (در مرحله 2)، نمایشی از دادههای جاری در
newState
ParcelFileDescriptor
بنویسید. مدیر پشتیبان گیری این شی را به صورت محلی به عنوان نمایشی از داده هایی که در حال حاضر پشتیبان گرفته شده اند، حفظ می کند. دفعه بعد کهonBackup()
را فراخوانی کرد، این را به عنوانoldState
به شما ارسال میکند، بنابراین میتوانید تعیین کنید که آیا نسخه پشتیبان دیگری لازم استoldState
همانطور که در مرحله 1 انجام شد. در طول تماس بعدی خالی شود.مثال زیر نمایشی از دادههای فعلی را با استفاده از مهر زمانی آخرین ویرایش فایل در
newState
ذخیره میکند:کاتلین
val modified = dataFile.lastModified() FileOutputStream(newState.fileDescriptor).also { DataOutputStream(it).apply { writeLong(modified) } }
جاوا
FileOutputStream outstream = new FileOutputStream(newState.getFileDescriptor()); DataOutputStream out = new DataOutputStream(outstream); long modified = dataFile.lastModified(); out.writeLong(modified);
یک بازیابی انجام دهید
هنگامی که زمان بازیابی اطلاعات برنامه شما فرا می رسد، مدیر پشتیبان گیری متد onRestore()
عامل پشتیبان شما را فراخوانی می کند. وقتی این روش را فراخوانی میکند، مدیر پشتیبانگیری دادههای پشتیبان شما را تحویل میدهد تا بتوانید آنها را در دستگاه بازیابی کنید.
فقط مدیر پشتیبان میتواند onRestore()
فراخوانی کند، که وقتی سیستم برنامه شما را نصب میکند و دادههای پشتیبان موجود را پیدا میکند، بهطور خودکار اتفاق میافتد.
هنگامی که مدیر پشتیبان گیری متد onRestore()
شما را فراخوانی می کند، سه پارامتر را ارسال می کند:
-
data
- یک شی
BackupDataInput
، که به شما امکان میدهد اطلاعات پشتیبان خود را بخوانید. -
appVersionCode
- یک عدد صحیح که مقدار مشخصه مانیفست
android:versionCode
برنامه شما را نشان میدهد، همانطور که در زمان پشتیبانگیری از این دادهها بود. می توانید از این برای بررسی متقاطع نسخه برنامه فعلی و تعیین اینکه آیا قالب داده سازگار است یا خیر استفاده کنید. برای اطلاعات بیشتر در مورد استفاده از این برای مدیریت نسخههای مختلف بازیابی دادهها، به بررسی نسخه بازیابی دادهها مراجعه کنید. -
newState
- یک
ParcelFileDescriptor
باز، خواندن/نوشتن که به فایلی اشاره میکند که در آن باید وضعیت پشتیبان نهایی را که باdata
ارائه شده است بنویسید. دفعه بعد کهonBackup()
فراخوانی شد، این شی به عنوانoldState
برگردانده می شود. به یاد داشته باشید که شما باید همان شیnewState
را در callbackonBackup()
نیز بنویسید—همچنین انجام آن در اینجا تضمین می کند که شیoldState
داده شده بهonBackup()
معتبر است حتی اولین باری کهonBackup()
پس از بازیابی دستگاه فراخوانی می شود.
در پیاده سازی onRestore()
باید readNextHeader()
روی data
فراخوانی کنید تا در تمام موجودیت های مجموعه داده تکرار شود. برای هر موجودیت یافت شده، موارد زیر را انجام دهید:
- کلید موجودیت را با
getKey()
دریافت کنید. کلید موجودیت را با لیستی از مقادیر کلید شناخته شده که باید به عنوان رشته های نهایی ثابت در کلاس
BackupAgent
خود اعلام می کردید مقایسه کنید. هنگامی که کلید با یکی از رشته های کلید شناخته شده شما مطابقت دارد، عبارتی را وارد کنید تا داده های موجودیت را استخراج کرده و در دستگاه ذخیره کنید:- اندازه داده موجودیت را با
getDataSize()
دریافت کنید و یک آرایه بایت با آن اندازه ایجاد کنید. -
readEntityData()
فراخوانی کنید و آرایه بایتی را به آن ارسال کنید، جایی که داده ها در آن قرار می گیرند، و شروع افست و اندازه خواندن را مشخص کنید. - آرایه بایت شما اکنون پر است. داده ها را بخوانید و هر طور که دوست دارید در دستگاه بنویسید.
- اندازه داده موجودیت را با
پس از خواندن و نوشتن دادههای خود در دستگاه، وضعیت دادههای خود را در پارامتر
newState
مانند آنچه در طولonBackup()
انجام میدهید، بنویسید.
به عنوان مثال، در اینجا نحوه بازیابی داده های پشتیبان گیری شده توسط مثال در بخش قبل آمده است:
کاتلین
@Throws(IOException::class) override fun onRestore(data: BackupDataInput, appVersionCode: Int, newState: ParcelFileDescriptor) { with(data) { // There should be only one entity, but the safest // way to consume it is using a while loop while (readNextHeader()) { when(key) { TOPSCORE_BACKUP_KEY -> { val dataBuf = ByteArray(dataSize).also { readEntityData(it, 0, dataSize) } ByteArrayInputStream(dataBuf).also { DataInputStream(it).apply { // Read the player name and score from the backup data playerName = readUTF() playerScore = readInt() } // Record the score on the device (to a file or something) recordScore(playerName, playerScore) } } else -> skipEntityData() } } } // Finally, write to the state blob (newState) that describes the restored data FileOutputStream(newState.fileDescriptor).also { DataOutputStream(it).apply { writeUTF(playerName) writeInt(mPlayerScore) } } }
جاوا
@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 playerName = in.readUTF(); playerScore = in.readInt(); // Record the score on the device (to a file or something) recordScore(playerName, playerScore); } 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(playerName); out.writeInt(mPlayerScore); }
در این مثال، پارامتر appVersionCode
ارسال شده به onRestore()
استفاده نمی شود. با این حال، ممکن است بخواهید از آن استفاده کنید اگر زمانی که نسخه کاربر از برنامه واقعاً به عقب برگشته است، یک نسخه پشتیبان تهیه کنید (به عنوان مثال، کاربر از نسخه 1.5 برنامه شما به 1.0 رفته است). برای اطلاعات بیشتر، بخش بعدی را ببینید.
نسخه بازیابی داده را بررسی کنید
وقتی مدیر پشتیبانگیری دادههای شما را در فضای ذخیرهسازی ابری ذخیره میکند، بهطور خودکار نسخه برنامه شما را که با ویژگی android:versionCode
فایل مانیفست شما تعریف شده است، شامل میشود. قبل از اینکه مدیر پشتیبان گیری با عامل پشتیبان شما تماس بگیرد تا داده های شما را بازیابی کند، به android:versionCode
برنامه نصب شده نگاه می کند و آن را با مقدار ثبت شده در مجموعه داده های بازیابی مقایسه می کند. اگر نسخه ضبط شده در مجموعه داده های بازیابی جدیدتر از نسخه برنامه در دستگاه باشد، کاربر برنامه خود را کاهش داده است. در این حالت، مدیر پشتیبانگیری عملیات بازیابی را برای برنامه شما لغو میکند و متد onRestore()
شما را فراخوانی نمیکند، زیرا مجموعه بازیابی برای نسخههای قدیمیتر بیمعنی در نظر گرفته میشود.
می توانید این رفتار را با ویژگی android:restoreAnyVersion
لغو کنید. این ویژگی را روی true
تنظیم کنید تا نشان دهد که میخواهید برنامه را بدون در نظر گرفتن نسخه تنظیم بازیابی بازیابی کنید. مقدار پیش فرض false
است. اگر این را روی true
تنظیم کنید، مدیر پشتیبان گیری android:versionCode
نادیده می گیرد و متد onRestore()
شما را در همه موارد فراخوانی می کند. در انجام این کار، می توانید به صورت دستی تفاوت نسخه را در متد onRestore()
خود بررسی کنید و در صورت عدم تطابق نسخه ها، هر اقدام لازم را برای سازگار کردن داده ها انجام دهید.
برای کمک به مدیریت نسخههای مختلف در طول عملیات بازیابی، متد onRestore()
کد نسخه همراه با مجموعه دادههای بازیابی را به عنوان پارامتر appVersionCode
به شما ارسال میکند. سپس میتوانید کد نسخه فعلی برنامه را با فیلد PackageInfo.versionCode
جستجو کنید. به عنوان مثال:
کاتلین
val info: PackageInfo? = try { packageManager.getPackageInfo(packageName, 0) } catch (e: PackageManager.NameNotFoundException) { null } val version: Int = info?.versionCode ?: 0
جاوا
PackageInfo info; try { String name = getPackageName(); info = getPackageManager().getPackageInfo(name, 0); } catch (NameNotFoundException nnfe) { info = null; } int version; if (info != null) { version = info.versionCode; }
سپس version
به دست آمده از PackageInfo
را با appVersionCode
که به onRestore()
منتقل شده مقایسه کنید.
درخواست یک نسخه پشتیبان
شما می توانید در هر زمان با فراخوانی dataChanged()
یک عملیات پشتیبان درخواست کنید. این روش به مدیر پشتیبانگیری اطلاع میدهد که میخواهید با استفاده از عامل پشتیبانگیری از اطلاعات خود نسخه پشتیبان تهیه کنید. سپس مدیر پشتیبان گیری متد onBackup()
عامل پشتیبان شما را در آینده فراخوانی می کند. معمولاً، هر بار که دادههایتان تغییر میکند، باید یک نسخه پشتیبان درخواست کنید (مانند زمانی که کاربر اولویت برنامه را تغییر میدهد که میخواهید از آن نسخه پشتیبان تهیه کنید). اگر قبل از درخواست پشتیبانگیری توسط مدیر پشتیبان، چندین بار dataChanged()
تماس بگیرید، نماینده شما همچنان فقط یک تماس با onBackup()
دریافت میکند.
درخواست بازیابی
در طول عمر عادی برنامه خود، نیازی به درخواست عملیات بازیابی ندارید. هنگامی که برنامه شما نصب می شود، سیستم به طور خودکار داده های پشتیبان را بررسی می کند و بازیابی را انجام می دهد.
به پشتیبانگیری خودکار مهاجرت کنید
میتوانید با تنظیم android:fullBackupOnly
روی true
در عنصر <application>
در فایل مانیفست، برنامه خود را به پشتیبانگیری کامل از دادهها انتقال دهید. وقتی روی دستگاهی با Android نسخه 5.1 (سطح API 22) یا پایینتر اجرا میشود، برنامه شما این مقدار را در مانیفست نادیده میگیرد و به انجام پشتیبانگیری با مقدار کلید ادامه میدهد. وقتی روی دستگاهی با Android نسخه 6.0 (سطح API 23) یا بالاتر اجرا میشود، برنامه شما به جای پشتیبانگیری با مقدار کلید، پشتیبانگیری خودکار انجام میدهد.
حریم خصوصی کاربر
در Google، ما به شدت از اعتماد کاربران به ما و مسئولیت خود در محافظت از حریم خصوصی کاربران آگاه هستیم. Google بهمنظور ارائه ویژگیهای پشتیبانگیری و بازیابی، دادههای پشتیبان را بهصورت ایمن به سرورهای Google و از آن منتقل میکند. Google با این داده ها به عنوان اطلاعات شخصی مطابق با خط مشی رازداری Google رفتار می کند.
علاوه بر این، کاربران می توانند عملکرد پشتیبان گیری از داده ها را از طریق تنظیمات پشتیبان گیری سیستم اندروید غیرفعال کنند. وقتی کاربر پشتیبانگیری را غیرفعال میکند، سرویس پشتیبانگیری Android همه دادههای پشتیبان ذخیرهشده را حذف میکند. یک کاربر میتواند پشتیبانگیری را در دستگاه دوباره فعال کند، اما Android Backup Service هیچ دادهای که قبلاً حذف شده را بازیابی نمیکند.