שמירת המצב עם מקטעים

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

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

  • משתנים: משתנים מקומיים בקטע.
  • מצב הצגת הנתונים: כל הנתונים ששייכים לתצוגה מפורטת אחת או יותר בקטע.
  • SaveState: נתונים שמוטבעים במופע המקטע הזה שצריך לשמור ב-onSaveInstanceState().
  • NonConfig: נתונים שנשלפו ממקור חיצוני, כגון שרת או מקומי מאגר נתונים, או נתונים שנוצרו על ידי משתמשים, שנשלחים לשרת לאחר המחויבות.

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

פעולה משתנים הצגת מצב מצב שמור ללא הגדרה
נוסף למקבץ האחורי x
שינוי הגדרה x
תהליך מוות/פנאי x ✓*
התמונה לא נוספה למקבץ האחורי x x x x
המארח הסתיים x x x x

* ניתן לשמור על מצב NonConfig גם במקרה של מוות של תהליך באמצעות מודול מצב שמור ל-ViewModel.

טבלה 1: פעולות הרסניות שונות של מקטעים וההשפעות שלהן שיש להם בסוגים שונים של מדינות.

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

אפליקציה ליצירת טקסט אקראי שמדגימה
            סוגי מדינות
איור 1. אפליקציה אקראית ליצירת טקסט שמדגימה של מדינות שונות.

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

נתונים סוג סוג המדינה תיאור
seed Long ללא הגדרה ערך הבסיס שמשמש ליצירה אקראית של מעשה טוב חדש. נוצר כאשר השדה ViewModel נוצר.
randomGoodDeed String מצב שמור + משתנה נוצר כשהקטע נוצר בפעם הראשונה. randomGoodDeed נשמר כדי לוודא שהמשתמשים יראו מעשה טוב אקראי גם לאחר תהליך מוות בילוי.
isEditing Boolean מצב שמור + משתנה הדגל הבוליאני מוגדר כ-true כאשר המשתמש מתחיל לערוך. הקובץ isEditing נשמר כדי לוודא שהחלק לעריכה של המסך ממשיך להיות גלוי כשיוצרים מחדש את המקטע.
טקסט ערוך Editable הצגת המדינה (בבעלות EditText) הטקסט הערוך בתצוגה EditText. התצוגה EditText שומרת את הטקסט הזה כדי לוודא שינויים בתהליך לא יאבדו.

טבלה 2: קובעת שהאפליקציה ליצירת טקסט אקראית חייבת לנהל.

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

הצגת המדינה

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

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

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

<EditText
    android:id="@+id/good_deed_edit_text"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

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

SavedState

המקטע שלך אחראי לניהול כמויות קטנות של מצב דינמי שהם חלק בלתי נפרד מהאופן שבו המקטע פועל. אפשר להמשיך סריאליזציה בקלות באמצעות Fragment.onSaveInstanceState(Bundle) דומה ל- Activity.onSaveInstanceState(Bundle) הנתונים שתציבו בחבילה יישמרו באמצעות שינויי הגדרות אישיות ולעבד מוות ופנאי, והם זמינים בחלק onCreate(Bundle), onCreateView(LayoutInflater, ViewGroup, Bundle), וגם onViewCreated(View, Bundle) שיטות.

בהמשך לדוגמה הקודמת, randomGoodDeed הוא המעשה ש תוצג למשתמש, ו-isEditing הוא דגל כדי לקבוע אם המקטע מציג או מסתיר את EditText. המצב השמור הזה צריך להיות המשיך להשתמש ב-onSaveInstanceState(Bundle), כפי שמוצג באופן הבא דוגמה:

Kotlin

override fun onSaveInstanceState(outState: Bundle) {
    super.onSaveInstanceState(outState)
    outState.putBoolean(IS_EDITING_KEY, isEditing)
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed)
}

Java

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putBoolean(IS_EDITING_KEY, isEditing);
    outState.putString(RANDOM_GOOD_DEED_KEY, randomGoodDeed);
}

כדי לשחזר את המצב ב-onCreate(Bundle), מאחזרים את הערך המאוחסן מ- החבילה:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    isEditing = savedInstanceState?.getBoolean(IS_EDITING_KEY, false)
    randomGoodDeed = savedInstanceState?.getString(RANDOM_GOOD_DEED_KEY)
            ?: viewModel.generateRandomGoodDeed()
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        isEditing = savedInstanceState.getBoolean(IS_EDITING_KEY, false);
        randomGoodDeed = savedInstanceState.getString(RANDOM_GOOD_DEED_KEY);
    } else {
        randomGoodDeed = viewModel.generateRandomGoodDeed();
    }
}

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

ללא הגדרה

יש למקם את נתוני NonConfig מחוץ למקטע שלך, למשל ViewModel. במשפט הקודם בדוגמה שלמעלה, seed (מצב ה-NonConfig שלנו) נוצר ב-ViewModel. הלוגיקה לשמירה על המצב שלו היא בבעלות ViewModel.

Kotlin

public class RandomGoodDeedViewModel : ViewModel() {
    private val seed = ... // Generate the seed

    private fun generateRandomGoodDeed(): String {
        val goodDeed = ... // Generate a random good deed using the seed
        return goodDeed
    }
}

Java

public class RandomGoodDeedViewModel extends ViewModel {
    private Long seed = ... // Generate the seed

    private String generateRandomGoodDeed() {
        String goodDeed = ... // Generate a random good deed using the seed
        return goodDeed;
    }
}

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

מקורות מידע נוספים

למידע נוסף על ניהול מצב מקטעים, ראה את המאמר הבא: משאבים נוספים.

שיעורי Lab

מדריכים