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

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

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

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

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

בתרשים הבא מוצג זרימת הנתונים במהלך גיבוי ושחזור בענן:

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

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

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

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

שירות הגיבוי הוא שירות מערכת של Android שמארגן ומתחיל פעולות גיבוי ושחזור. אפשר לגשת לשירות דרך ה-API של 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, ולכן יכול להיות ששיטות ההגדרה של האפליקציה לא יופעלו. הגיבוי האוטומטי גם לא מפעיל אף אחת מהפעילויות של האפליקציה, ולכן יכול להיות שיוצגו שגיאות אם האפליקציה מבצעת הגדרה בפעילות. מידע נוסף מופיע במאמר הטמעה של 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 משלכם, סביר להניח שלא הוספתם נתונים או קבצים לגיבוי.