בדיקת הגיבוי והשחזור

בדף הזה מוסבר איך לבדוק את הגיבויים בענן ואת תהליך ההעברה ממכשיר למכשיר (D2D) של האפליקציה. חשוב לבדוק את שניהם בכל גרסה ראשית של האפליקציה כדי לוודא שהמשתמשים יוכלו להמשיך להשתמש באפליקציה במכשיר חדש. למרות שהגיבוי וההעברה דומים, יש ביניהם הבדלים חשובים ב-Android מגרסה 12 (רמת API‏ 31) ומעלה. ההבדל הבולט ביותר הוא שההעברה מוגבלת לגודל נתונים של 2 GB, לעומת 25 MB לגיבוי בענן.

במדריך הזה נסביר איך אפשר לבדוק ביעילות את הגיבוי והשחזור בענן ואת ההעברה מ-D2D לאורך מחזור הפיתוח.

איך פועלת בדיקת גיבויים

בקטע הזה מתוארים חלקים שונים במסגרת הגיבוי של Android, ומוסבר איך הם פועלים עם אפליקציות שתומכות בגיבוי אוטומטי ובגיבוי של צמדי מפתח/ערך. במהלך שלב פיתוח האפליקציה, רוב הפעולות הפנימיות של המסגרת מופשטות, כך שלא צריך לדעת את המידע הזה. עם זאת, בשלב הבדיקה, חשוב יותר להבין את המושגים האלה.

בתרשים הבא מוצג תהליך זרימת הנתונים במהלך גיבוי ושחזור בענן. למטרות בדיקה, אפשר להשתמש באותו מכשיר לגיבוי בענן ולשחזור.

זרימת נתונים במסגרת הגיבוי

התרשים הבא ממחיש את זרימת הנתונים במהלך העברה מ-D2D:

זרימת נתונים במסגרת העברת נתונים

בניגוד לבדיקות של גיבוי ושחזור בענן, בדיקות D2D דורשות מכשיר מקור ומכשיר יעד להעתקה.

Backup Manager Service הוא שירות מערכת של Android שמארגן ומתחיל פעולות גיבוי ושחזור. אפשר לגשת לשירות באמצעות ה-API‏ Backup Manager.

במהלך פעולת גיבוי, השירות שולח שאילתה לאפליקציה כדי לקבל נתוני גיבוי, ואז מעביר אותם אל העברת הגיבוי, שמאחסנת את הנתונים בענן. במהלך פעולת שחזור, שירות ניהול הגיבוי מאחזר את נתוני הגיבוי מהעברת הגיבוי ומשחזר את הנתונים למכשיר. בהעברה ממכשיר למכשיר, שירות Backup Manager שולח שאילתה לאפליקציה כדי לקבל נתוני גיבוי ומעביר אותם ישירות לשירות Backup Manager במכשיר החדש, שמעמיס אותם לאפליקציה.

Backup Transports הם רכיבי Android שאחראים לאחסון ולשליפה של נתוני האפליקציות. במכשיר עם Android יכולים להיות אפס או יותר אמצעי גיבוי, אבל רק אחד מהם יכול להיות מסומן כפעיל. אמצעי התעבורה הזמינים לגיבוי משתנים ממכשיר למכשיר, בגלל התאמות אישיות של יצרני המכשירים וספקי השירותים, אבל רוב המכשירים עם Google Play מגיעים עם אמצעי התעבורה הבאים:

  • GMS Transport: העברת הגיבוי הפעילה בענן ברוב המכשירים, חלק מ-Google Mobile Services. הנתונים מועברים דרך פרוטוקול זה ומאוחסנים בשירות הגיבוי של Android.
  • העברה ממכשיר למכשיר (D2D): ההעברה הזו משמשת בהעברה ממכשיר למכשיר כדי להעביר נתונים ישירות ממכשיר אחד למכשיר אחר.

כלים

כדי לבדוק את פעולות הגיבוי והשחזור, צריך להכיר קצת את הכלים הבאים.

  • adb: להרצת פקודות במכשיר או באמולטור.
  • bmgr: לביצוע פעולות שונות של גיבוי ושחזור.
  • logcat: כדי לראות את הפלט של פעולות הגיבוי והשחזור.

בדיקת הגיבוי בענן

אפשר לבצע גיבוי ושחזור בענן באמצעות מכשיר יחיד לפי השלבים שמפורטים בקטע הזה.

הכנת המכשיר או האמולטור לגיבויים בענן

כדי להכין את המכשיר או האמולטור לבדיקת הגיבוי, צריך לעבור על רשימת המשימות הבאה:

  1. כדי להשתמש בגיבוי אוטומטי, צריך לוודא שאתם משתמשים במכשיר או באמולטור עם Android בגרסה 6.0 ומעלה (רמת API‏ 23).
  2. לגיבוי של זוגות מפתח/ערך, צריך לוודא שאתם משתמשים במכשיר או באמולטור עם Android מגרסה 2.2 (רמת API‏ 8) ומעלה.
  3. כדי לבדוק את הגיבוי בענן, צריך גישה לאינטרנט.
  4. נכנסים למכשיר באמצעות חשבון Google ומגדירים אותו כחשבון הגיבוי בהגדרות -> Google -> גיבוי.

כדי לבדוק את הגיבוי בענן, מפעילים גיבוי בענן, ואז מסירים את האפליקציה ומתקינים אותה מחדש. כדי שהשלבים האלה יהיו ניתנים לחזרה, אפשר להשתמש בסקריפט הבא, test_cloud_backup.sh, שמגבה את האפליקציה, מוריד את ה-APK באופן מקומי, מסיר אותו ומתקין מחדש את ה-APK:

#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell bmgr transport com.android.localtransport/.LocalTransport | grep -q "Selected transport" || (echo "Error: error selecting local transport"; exit 1)
adb shell settings put secure backup_local_transport_parameters 'is_encrypted=true'
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

שלבי הבדיקה

  1. פותחים את האפליקציה, מתחברים ומשנים את כל ההגדרות.
  2. מריצים את הסקריפט ומעבירים את שם החבילה, לדוגמה: test_cloud_backup.sh com.example.myapp
  3. פותחים מחדש את האפליקציה ומוודאים שהיא פועלת בצורה תקינה ושכל הנתונים נשמרו.

אתם לא רוצים שהמשתמשים יצטרכו להתחבר, וכל ההגדרות, ההתקדמות והנתונים של האפליקציה צריכים להיות כמו שהם היו לפני כן. אם תוצאות הבדיקה לא עומדות בקריטריונים האלה, צריך לוודא שהגדרתם את הגיבויים בצורה נכונה, בלי להשמיט נתונים חשובים, וגם שאתם מטפלים ביצירה מחדש של נתונים במטמון שהחרגתם מהגיבוי. חוזרים על שלבים 1-3 לכל איטרציה של בדיקה.

בדיקת העברה מ-D2D

הדרך המקיפה ביותר לבדוק את ההעברה ממכשיר למכשיר היא להעביר את כל התוכן בטלפון למכשיר חדש שאופס להגדרות המקוריות, ולוודא שההעברה פועלת בצורה תקינה. אבל אם צריך לחזור על התהליך כמה פעמים, זה יכול להיות לא נוח ולגזול זמן. בשלבים הבאים מוסבר איך לדמות העברה עם מכשיר יחיד בלי לבצע שוב ושוב איפוס להגדרות המקוריות במכשיר.

הכנת המכשיר לבדיקת D2D

כדי לבדוק העברה ממכשיר למכשיר במכשיר יחיד, צריך להכין אותו באופן הבא:

  1. במכשיר צריכה להיות מותקנת מערכת Android מגרסה 12 (רמת API ‏31) ואילך.
  2. כדי לבדוק את הגרסה העדכנית של D2D, צריך לטרגט את Android 12 (רמת API ‏31) ואילך באפליקציה.
  3. יוצרים את הסקריפט הבא, test_d2d.sh, כדי לתמוך בחזרה על הבדיקה:
#!/bin/bash -eu
: "${1?"Usage: $0 package name"}"

# Initialize and create a backup
adb shell bmgr enable true
adb shell settings put secure backup_enable_d2d_test_mode 1
adb shell bmgr transport com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell bmgr list transports | grep -q -F "  * com.google.android.gms/.backup.migrate.service.D2dTransport" || (echo "Failed to select and initialize backup transport"; exit 1)
adb shell bmgr backupnow "$1" | grep -F "Package $1 with result: Success" || (echo "Backup failed"; exit 1)

# Uninstall and reinstall the app to clear the data and trigger a restore
apk_path_list=$(adb shell pm path "$1")
OIFS=$IFS
IFS=$'\n'
apk_number=0
for apk_line in $apk_path_list
do
    (( ++apk_number ))
    apk_path=${apk_line:8:1000}
    adb pull "$apk_path" "myapk${apk_number}.apk"
done
IFS=$OIFS
adb shell pm uninstall --user 0 "$1"
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
apks=$(seq -f 'myapk%.f.apk' 1 $apk_number)
adb install-multiple -t --user 0 $apks

# Clean up
adb shell bmgr init com.google.android.gms/.backup.migrate.service.D2dTransport
adb shell settings put secure backup_enable_d2d_test_mode 0
adb shell bmgr transport com.google.android.gms/.backup.BackupTransportService
rm $apks

echo "Done"

שלבי הבדיקה

  1. מתקינים במכשיר את האפליקציה שרוצים לבדוק.
  2. פותחים את האפליקציה, מתחברים ומשנים את ההגדרות שלה.
  3. מריצים את הסקריפט במכשיר ומעבירים את שם החבילה, לדוגמה: test_d2d.sh com.example.myapp.
  4. כשהסקריפט מסתיים, פותחים את האפליקציה במכשיר ומוודאים שהיא פועלת בצורה תקינה ושכל הנתונים נשמרים.

אתם לא רוצים שהמשתמשים יצטרכו להתחבר לחשבון, וכל ההגדרות, ההתקדמות והנתונים של האפליקציה צריכים להופיע כמו שהם הופיעו לפני הפעלת הסקריפט. אם תוצאות הבדיקה לא עומדות בקריטריונים האלה, צריך לוודא שהגדרתם את ההעברה בצורה נכונה, בלי להשמיט חלקים חשובים מהנתונים, וגם שאתם מטפלים ביצירה מחדש של נתונים במטמון שהחרגתם מההעברה. חוזרים על שלבים 2-4 לכל איטרציה של הבדיקה.

פתרון בעיות בגיבוי ובשחזור

בקטע הזה מוסבר איך לפתור כמה בעיות נפוצות.

חריגה ממכסת ההעברה

ההודעות הבאות ב-Logcat מציינות שהאפליקציה חרגה מהמיכסה של שכבת התעבורה:

I/PFTBT: Transport rejected backup of <PACKAGE>, skipping

--- or ---

I/PFTBT: Transport quota exceeded for package: <PACKAGE>

צריך להקטין את כמות הנתונים לגיבוי ולנסות שוב. לדוגמה, צריך לוודא שאתם שומרים נתונים במטמון רק בספריית המטמון של האפליקציה. ספריית המטמון לא נכללת בגיבויים.

אי אפשר לבצע גיבוי מלא

ההודעה הבאה ב-Logcat מציינת שפעולת הגיבוי המלא נכשלה כי עדיין לא בוצעה במכשיר פעולת גיבוי של צמדי מפתח/ערך:

I/BackupManagerService: Full backup not currently possible -- key/value backup
not yet run?

מפעילים גיבוי של זוגות מפתח/ערך באמצעות הפקודה bmgr run, ואז מנסים שוב.

הזמן הקצוב לתפוגה בהמתנה לנציג

ההודעה הבאה ב-Logcat מציינת שהאפליקציה שלך נטענת לגיבוי יותר מ-10 שניות:

12-05 18:59:02.033  1910  2251 D BackupManagerService:
    awaiting agent for ApplicationInfo{5c7cde0 com.your.app.package}
12-05 18:59:12.117  1910  2251 W BackupManagerService:
    Timeout waiting for agent ApplicationInfo{5c7cde0 com.your.app.package}
12-05 18:59:12.117  1910  2251 W BackupManagerService:
    Can't find backup agent for com.your.app.package

שימו לב להבדל בחותמת הזמן בפלט של היומן. השגיאה הזו מתרחשת בדרך כלל כשהאפליקציה משתמשת בהגדרת multidex ללא ProGuard.

חשבון גיבוי שלא אותחל

ההודעות הבאות ב-Logcat מציינות שהגיבוי הופסק כי מערך נתוני הגיבוי לא אותחל:

01-31 14:32:45.698 17280 17292 I Backup: [GmsBackupTransport] Try to backup for
an uninitialized backup account.
01-31 14:32:45.699  1043 18255 W PFTBT: Transport failed; aborting backup: -1001
01-31 14:32:45.699  1043 18255 I PFTBT: Full backup completed with status: -1000

מריצים את כלי הגיבוי באמצעות הפקודה adb shell bmgr run ומנסים לבצע שוב את הגיבוי.

App methods not called

הגיבוי האוטומטי מפעיל את האפליקציה עם מחלקת בסיס של Application, ולכן יכול להיות שהשיטות להגדרת האפליקציה לא יופעלו. גם הגיבוי האוטומטי לא מפעיל אף אחת מהפעילויות של האפליקציה, כך שאם האפליקציה מבצעת הגדרה בפעילות, יכול להיות שיוצגו שגיאות. מידע נוסף זמין במאמר Implement BackupAgent.

לעומת זאת, גיבוי של צמדי מפתח/ערך מפעיל את האפליקציה עם כל מחלקת משנה Application שמצהירים עליה בקובץ המניפסט של האפליקציה.

אין נתונים לגיבוי

ההודעות הבאות ב-Logcat מציינות שלאפליקציה אין נתונים לגיבוי:

I Backup  : [FullBackupSession] Package com.your.app.package doesn't have any backup data.

--- or ---

I Backup  : [D2dTransport] Package com.your.app.package doesn't have any backup data.

אם הטמעתם גיבוי משלכם BackupAgent, סביר להניח שלא הוספתם נתונים או קבצים לגיבוי.