
executePendingTransactions פותרת את זה.getSupportFragmentManager().beginTransaction().replace(...) לתוך R.id.FragmentLayoutContainer. (בהדגמה זה אותו סוג פרגמנט, ובמציאות בדרך כלל תהיה מחלקה אחרת.)displayAnimal, והאפליקציה נופלת על NullPointerException בקריאה ל-setImageResource על אובייקט null.onCreateView. הפונקציה רצה רק כשהפרגמנט מתווסף לאקטיביטי ומתחיל מחזור החיים שלה, והטרנזקציה אסינכרונית, כך שהקוד המשיך לפני שה-view אותחל.getSupportFragmentManager().executePendingTransactions(). היא מורה למערכת לסיים עכשיו את כל הטרנזקציות הממתינות, וכך הופכת את הפעולה מאסינכרונית לסינכרונית.onCreate, אם כי מותר גם שם מיד אחרי טרנזקציה.replace, add ו-remove על ה-fragment manager, ו-executePendingTransactions().הטקסט המלא של הדקות הראשונות בהרצאה «הרצת Pending Transactions» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
קורה לפעמים שאנחנו רוצים במהלך חיי האפליקציה להחליף פרגמנט. אנחנו ראינו את זה בהתחלה כשהתחלנו רק לעבוד עם פרגמנט, וראינו שקיימת פונקציה שנקראת replace, במקום פונקציה שנקראת add, או בנוסף ל-add.
ראינו שקיימות add, replace ו-remove. אז אם אנחנו רוצים להחליף את הפרגמנט, אז אנחנו רוצים כמובן לקרוא ל-replace עם אובייקט פרגמנט אחר, וכמובן, להמשיך לעבוד עם האובייקט החדש.
בואו רגע נבצע הדמיה כזאת כאן. בלחיצה על הלחצן, אם אנחנו נרצה לבצע החלפה של אובייקט הפרגמנט, אז אנחנו נצטרך לבצע משהו כזה. נקרא ל-AnimalFragment, שווה NewAnimalFragment, הנה יש לנו פה אובייקט פרגמנט חדש לגמרי, ונבצע getSupportFragmentManager בגיןTransactionReplace
לתוך R.id.FragmentLayoutContainer. אנחנו רוצים לשלוח את האנימל פרגמנט כאובייקט חדש שיצרנו. עכשיו כאן נראה שאם אנחנו נרצה לבצע דבר כזה במציאות, זה לא יהיה אותו אובייקט פרגמנט, אלא יהיה אובייקט פרגמנט אחר.
ואנחנו רק עושים פה איזשהו דמו כזה שאנחנו בעצם רוצים אובייקט פרגמנט חדש לגמרי במציאות כנראה שזה יהיה מחלקת פרגמנט אחרת לחלוטין. אבל אם אנחנו מבצעים את זה ויש לנו כאן אובייקט פרגמנט חדש לגמרי ומצרפים אותו ואז מיד משתמשים בו יכול להיות שתהיה פה איזושהי בעיה.
בואו נבדוק קודם כל איך האפליקציה עובדת בשלב הזה. התוכנית עולה בלי שום בעיה, ובואו נלחץ על לחצן, ואנחנו חוטפים קריסה. בואו נסתכל רגע מה בדיוק הבעיה שהייתה כאן.
ניגש לקריסה, נלחץ על הלינק, ונראה שאנחנו נופלים על null pointer exception, attempt to invoke virtual method, והמתוד הנקראת set image resource, on a null object reference.
זאת אומרת בדיוק אנחנו רואים גם שהוא מסמן לנו את השורה הזאת ואומר לנו איך אתם יכולים לקרוא לסט image resource ולשלוח איזשהו מידע אינטג'רי כאשר האובייקט הזה הוא נל. אבל למה שהאובייקט הזה יהיה נל? הרי זה בעצם אחד מהאובייקטים שקיימים בלהוט שלנו ואנחנו יודעים כמובן שonCreateView התבצעה והכל בסדר.
אז למעשה מה שקרה כאן זה שכאשר אנחנו יוצרים אובייקט חדש עדיין הפונקציה onCreateView לא מתבצעת. כאשר אנחנו מוסיפים את הפרגמנט לאקטיביטי אז בעצם מתחיל להתבצע כל הפרגמנט לייף סייקל שאחד מהם זה הפונקציה onCreateView.
ולמעשה מה שקרה כאן זה שעד שכל הסיפור הזה הסתיים אנחנו כבר המשכנו וקראנו לדיספליי אנימל וניסינו בעצם להציג את המידע בתוך הפונקציה דיספליי אנימל וניגשנו לאובייקט שהוא עדיין לא הותחל ובעצם מחזיק נל.
אנחנו צריכים לבצע פה איזשהו זירוז של התהליכים ולהגיד למערכת תסיימי בבקשה את כל הפעילות שלך כי אנחנו רוצים להתחיל להשתמש בפרגמנט. והפקודה הזאת, זאת הפקודה הבאה.
Get Support Fragment Manager נקודה Execute Pending Transaction. הטרנזקשן שהתבצע כאן היא הייתה אסינכרונית והמערכת המשיכה והטרנזקציה לא באמת הסתיימה. execute pending transaction זאת פונקציה שאומרת למערכת בואי בשלב הזה תסיימי את כל הטרנזקציות הפתוחות שלך כי אנחנו רוצים בעצם להתחיל לעבוד עם הפרגמנט ממש ממש מיד ולכן אנחנו הופכים
בעצם את הפעילות האסינכרונית לפעילות סינכרונית כאשר אנחנו ממתינים עד שכל הטרנזקציות יתבצעו ואז אנחנו יכולים להשתמש עם זה. בדרך כלל אנחנו נרצה להשתמש ב-Execute Pending Transaction, כאשר אנחנו רוצים מידית לפתוח פריגמנט ולהשתמש איתה, זה בדרך כלל יהיה בתוך לחצנים או בתוך כל מיני אירועים, זה פחות יהיה ב-On Create,
למרות שאין מניעה גם מיד אחרי ביצוע טרנזקציה ב-On Create לבצע את Execute Pending Transaction. אז בואו רגע נריץ שוב פעם, הנה אנחנו רואים שאנחנו רצים, נלחץ על הלחצן, והכל בסדר, נפטרה בעיה בעזרת