לכל מכונה של Fragment
יש מחזור חיים משלה. כשמשתמש מנווט באפליקציה ומקיים אינטראקציה איתה, הקטעים עוברים מצבים שונים במהלך מחזור החיים שלהם, כאשר הם מתווספים, מוסרים, נכנסים למסך או יוצאים ממנו.
כדי לנהל את מחזור החיים, Fragment
מטמיע את LifecycleOwner
, ומציג אובייקט Lifecycle
שאפשר לגשת אליו באמצעות השיטה getLifecycle()
.
כל מצב אפשרי של Lifecycle
מיוצג במערך הערכים Lifecycle.State
.
כשמפתחים את Fragment
מעל Lifecycle
, אפשר להשתמש בשיטות ובכיתות שזמינות לטיפול במחזורי חיים באמצעות רכיבים מודעים למחזור החיים.
לדוגמה, אפשר להציג את המיקום של המכשיר במסך באמצעות רכיב שמתחשב במחזור החיים. הרכיב הזה יכול להתחיל להאזין באופן אוטומטי כשהקטע הופך לפעיל ולהפסיק כשהקטע עובר למצב לא פעיל.
כחלופה לשימוש ב-LifecycleObserver
, הכיתה Fragment
כוללת שיטות קריאה חוזרת (callback) שתואמות לכל אחד מהשינויים במחזור החיים של קטע הקוד. אלה כוללים את onCreate()
, onStart()
, onResume()
, onPause()
, onStop()
ו-onDestroy()
.
לתצוגה של קטע יש Lifecycle
נפרד שמנוהל בנפרד מ-Lifecycle
של הקטע. לכל קטע יש LifecycleOwner
משלו, שאפשר לגשת אליו באמצעות getViewLifecycleOwner()
או getViewLifecycleOwnerLiveData()
.
הגישה ל-Lifecycle
של התצוגה שימושית במצבים שבהם רכיב עם תמיכה במחזור חיים צריך לבצע פעולות רק בזמן שהתצוגה של החלק הקיימת, למשל מעקב אחרי LiveData
שמיועד להופיע רק במסך.
בנושא הזה נסביר בפירוט את מחזור החיים של Fragment
, נציג חלק מהכללים שקובעים את מצב מחזור החיים של קטע קוד ונסביר את הקשר בין המצבים של Lifecycle
לבין פונקציות ה-callbacks של מחזור החיים של קטע הקוד.
קטעים ומנהל הקטעים
כשיוצרים מופע של קטע קוד, הוא מתחיל במצב INITIALIZED
. כדי שקטע קוד יוכל לעבור את שאר שלבי מחזור החיים שלו, צריך להוסיף אותו ל-FragmentManager
. ה-FragmentManager
אחראי לקבוע באיזה מצב צריך להיות הפלח שלו, ולאחר מכן להעביר אותו למצב הזה.
מעבר למחזור החיים של הקטעים, FragmentManager
אחראי גם לקישור קטעים לפעילות המארחת שלהם ולניתוק שלהם כשהקטע כבר לא בשימוש. לכיתה Fragment
יש שתי שיטות קריאה חוזרת (callbacks), onAttach()
ו-onDetach()
, שאפשר לשנות כדי לבצע פעולות כשאחד מהאירועים האלה מתרחש.
פונקציית ה-callback של onAttach()
מופעלת כשהקטע נוסף ל-FragmentManager
ומצורף לפעילות המארחת שלו. בשלב הזה, החלק הפעיל וה-FragmentManager
מנהלים את מצב מחזור החיים שלו. בשלב הזה, שיטות FragmentManager
כמו findFragmentById()
מחזירות את הקטע הזה.
תמיד קוראים ל-onAttach()
לפני כל שינוי במצב של מחזור החיים.
פונקציית הקריאה החוזרת onDetach()
מופעלת כשהקטע הוסר מ-FragmentManager
והתנתק מהפעילות המארחת שלו. הפלח כבר לא פעיל ואי אפשר לאחזר אותו באמצעות findFragmentById()
.
onDetach()
תמיד נקרא אחרי שינויים במצב של מחזור החיים.
חשוב לדעת שהקריאות החוזרות האלה לא קשורות לשיטות attach()
ו-detach()
של FragmentTransaction
.
מידע נוסף על השיטות האלה זמין במאמר פיצול עסקאות.
מצבים של מחזור חיים של קטעי קוד וקריאות חוזרות
כדי לקבוע את מצב מחזור החיים של קטע קוד, FragmentManager
מתייחס לגורמים הבאים:
- המצב המקסימלי של קטע נקבע לפי
FragmentManager
שלו. הפלח לא יכול להתקדם מעבר למצב שלFragmentManager
שלו. - כחלק מ-
FragmentTransaction
, אפשר להגדיר מצב מקסימלי של מחזור חיים בחלק באמצעותsetMaxLifecycle()
. - מצב מחזור החיים של קטע לא יכול להיות גבוה יותר מזה של הרכיב ההורה שלו. לדוגמה, צריך להפעיל את הפעילות או את קטע הקוד ההורה לפני שמפעילים את קטעי הקוד הצאצאים. באופן דומה, צריך להפסיק את הפעולה של קטעי הקוד הצאצאים לפני הפעולה של הפעילות או של קטע הקוד ההורה.
![מצבי מחזור החיים של הפלח והקשר שלהם לקריאות החזרה (callbacks) של מחזור החיים של הפלח ולמחזור החיים של התצוגה של הפלח](https://developer.android.google.cn/static/images/guide/fragments/fragment-view-lifecycle.png?authuser=0&hl=he)
Lifecycle
והקשר שלהם גם ל-callbacks של מחזור החיים של ה-Fragment וגם לתצוגה Lifecycle
של ה-Fragment.באיור 1 מוצגים כל המצבים של Lifecycle
ב-fragment, והאופן שבו הם קשורים גם ל-callbacks של מחזור החיים של ה-fragment וגם לתצוגה Lifecycle
של ה-fragment.
ככל שהקטע מתקדם במחזור החיים שלו, הוא עובר למעלה ולמטה במצבים שלו. לדוגמה, קטע שמתווסף לחלק העליון של סטאק הקודם עובר למעלה מ-CREATED
ל-STARTED
ל-RESUMED
. לעומת זאת, כשקטע מודחק מהמקבץ הקודם, הוא עובר למטה דרך המצבים האלה, מ-RESUMED
ל-STARTED
ל-CREATED
ולבסוף ל-DESTROYED
.
מעברים למצבים גבוהים יותר
כשהקטע עובר למצבים הבאים במחזור החיים שלו, הוא קורא קודם ל-callback המשויך למחזור החיים של המצב החדש. בסיום הקריאה החוזרת, האירוע הרלוונטי Lifecycle.Event
יועבר לצופים על ידי Lifecycle
של החלק, ולאחר מכן על ידי התצוגה Lifecycle
של החלק, אם נוצרה.
מקטע נוצר
כשהמקטע מגיע למצב CREATED
, הוא כבר נוסף ל-FragmentManager
והשיטה onAttach()
כבר הוזמנה.
זהו המקום המתאים לשחזור כל מצב ששמור ומשויך לקטע עצמו באמצעות SavedStateRegistry
של הקטע.
חשוב לזכור שהתצוגה של החלק הקטן לא נוצרה בשלב הזה, וכל מצב שמשויך לתצוגה של החלק הקטן צריך להיות משוחזר רק אחרי יצירת התצוגה.
המעבר הזה מפעיל את הפונקציה החוזרת onCreate()
. פונקציית הקריאה החוזרת מקבלת גם את הארגומנט savedInstanceState
Bundle
שמכיל את כל המצבים שנשמרו בעבר על ידי
onSaveInstanceState()
.
חשוב לזכור של-savedInstanceState
יש ערך null
בפעם הראשונה שהקטע נוצר, אבל הוא תמיד לא null ביצירות חוזרות, גם אם לא מבטלים את ברירת המחדל של onSaveInstanceState()
. פרטים נוספים זמינים במאמר שמירה של מצב באמצעות קטעים.
אירועי CREATED ו-View INITIALIZED של מקטע
התצוגה Lifecycle
של החלק המוצג נוצרת רק כש-Fragment
מספק מופע חוקי של View
. ברוב המקרים, אפשר להשתמש במגדירי הקטעים שמקבלים @LayoutId
, שמנפח את התצוגה באופן אוטומטי בזמן המתאים. אפשר גם לשנות את ברירת המחדל של onCreateView()
כדי ליצור או לנפח את התצוגה של החלק באופן פרוגרמטי.
אם View
שמשמש ליצירת המופע של תצוגת הפלח הוא לא null, ה-View
הזה מוגדר בפלח וניתן לאחזר אותו באמצעות getView()
. לאחר מכן, הערך של getViewLifecycleOwnerLiveData()
מתעדכן בערך החדש של INITIALIZED
LifecycleOwner
שתואם לתצוגה של הקטע. באותו זמן מתבצעת גם קריאה חוזרת במחזור החיים של onViewCreated()
.
זהו המקום המתאים להגדרת המצב הראשוני של התצוגה, להתחיל לעקוב אחרי מכונות LiveData
שהקריאות החוזרות שלהן מעדכנות את התצוגה של החלק, ולהגדיר מתאמים לכל מכונות RecyclerView
או ViewPager2
בתצוגה של החלק.
יצירת קטעים ותצוגות
אחרי יצירת התצוגה של החלק, מצב התצוגה הקודם, אם יש כזה, משוחזר, ואז Lifecycle
של התצוגה מועבר למצב CREATED
. הבעלים של מחזור החיים של התצוגה גם משדר את האירוע ON_CREATE
למשתמשי הצפייה. כאן צריך לשחזר כל מצב נוסף שמשויך לתצוגה של החלק.
המעבר הזה גם מפעיל את הפונקציה החוזרת (callback) onViewStateRestored()
.
'התחלה' של פרגמנט ותצוגה
מומלץ מאוד לקשר רכיבים מודעים למחזור חיים למצב STARTED
של קטע, כי המצב הזה מבטיח שהתצוגה של הקטע זמינה, אם נוצרה כזו, ושבטוח לבצע FragmentTransaction
על הצאצא FragmentManager
של הקטע. אם התצוגה של ה-fragment לא null, התצוגה Lifecycle
של ה-fragment תועבר אל STARTED
מיד אחרי שה-Lifecycle
של ה-fragment יועבר אל STARTED
.
כשהקטע הופך ל-STARTED
, מתבצעת קריאה חוזרת (callback) ל-onStart()
.
'הפרגמנט והתצוגה הומשכו'
כשהקטע גלוי, כל ההשפעות של Animator
ושל Transition
מסתיימות, והקטע מוכן לאינטראקציה של המשתמש. הערך של Lifecycle
של החלק המודגש עובר למצב RESUMED
, והפונקציה הלא סטטית onResume()
מופעלת.
המעבר ל-RESUMED
הוא האות המתאים שמציין שהמשתמש יכול עכשיו לקיים אינטראקציה עם החלק. בקטעי קוד שאינם RESUMED
אסור להגדיר באופן ידני את המיקוד בתצוגות שלהם או לנסות לטפל בחשיפה של שיטת הקלט.
מעברים למצבים נמוכים יותר
כשקטע נע למטה למצב נמוך יותר במחזור החיים, האירוע הרלוונטי Lifecycle.Event
מונפק למתבוננים על ידי התצוגה Lifecycle
של הקטע, אם נוצרה, ואחריו Lifecycle
של הקטע. אחרי שהאירוע של מחזור החיים של החלק מופעל, החלק קורא ל-callback המשויך של מחזור החיים.
'התחלה' של פרגמנט ותצוגה
כשהמשתמש מתחיל לצאת מהקטע, ובזמן שהקטע עדיין גלוי, ה-Lifecycle
של הקטע ושל התצוגה שלו מועברים חזרה למצב STARTED
ומפיצים את האירוע ON_PAUSE
למשתמשי הצפייה שלהם. לאחר מכן, החלק מפעיל את פונקציית הקריאה החוזרת שלו, onPause()
.
יצירת קטעים ותצוגות
כשהקטע כבר לא גלוי, ה-Lifecycle
של הקטע ושל התצוגה שלו מועברים למצב CREATED
ומפיצים את האירוע ON_STOP
למשתמשי המעקב שלהם. מעבר המצב הזה מופעל לא רק על ידי הפסקת הפעילות או הפלח ההורה, אלא גם על ידי שמירת המצב על ידי הפעילות או הפלח ההורה. ההתנהגות הזו מבטיחה שהאירוע ON_STOP
יופעל לפני שמצב הפלח נשמר. לכן, האירוע ON_STOP
הוא הנקודה האחרונה שבה אפשר לבצע FragmentTransaction
על הצאצא FragmentManager
.
כפי שמוצג באיור 2, הסדר של קריאת החזרה (callback) של onStop()
ושמירת המצב באמצעות onSaveInstanceState()
משתנה בהתאם לרמת ה-API. בכל רמות ה-API שקדמו ל-API 28, onSaveInstanceState()
מופעל לפני onStop()
.
ברמת API 28 ואילך, סדר הקריאה הפוך.
![הבדלים בסדר הקריאה של onStop() ו-onSaveInstanceState()](https://developer.android.google.cn/static/images/guide/fragments/stop-save-order.png?authuser=0&hl=he)
onStop()
ושל onSaveInstanceState()
.
אירוע CREATED של קטע קוד ותצוגה שהושמדה
אחרי שכל האנימציות והמעברים של היציאה מסתיימים, והתצוגה של החלק מנותקת מהחלון, התצוגה Lifecycle
של החלק מועברת למצב DESTROYED
ומפיצה את האירוע ON_DESTROY
למתבוננים שלה. לאחר מכן, ה-fragment מפעיל את הפונקציה החוזרת שלו, onDestroyView()
. בשלב הזה, התצוגה של החלק המודגש הגיעה לסוף מחזור החיים שלה ו-getViewLifecycleOwnerLiveData()
מחזירה את הערך null
.
בשלב הזה צריך להסיר את כל ההפניות לתצוגה של החלק, כדי לאפשר איסוף אשפה של התצוגה של החלק.
מקטע DESTROYED
אם הפלח יוסר או אם FragmentManager
נהרס, הערך של Lifecycle
בפלח יועבר לסטטוס DESTROYED
והוא ישלח את האירוע ON_DESTROY
למשתמשי הצפייה שלו. לאחר מכן, ה-fragment מפעיל את הפונקציה החוזרת שלו, onDestroy()
. בשלב הזה, הקטע הגיע לסוף מחזור החיים שלו.
מקורות מידע נוספים
למידע נוסף על מחזור החיים של הפלח, תוכלו לעיין במקורות המידע הנוספים הבאים.