קורות חיים מרובות

ב-Android 9 (וגרסאות קודמות), אפליקציות הועברו למצב PAUSED כאשר:

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

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

ב-Android 10, כל הפעילויות שניתנות למיקוד מובילות במקבצים הגלויים נמצאות את המצב RESUMED. כך אפשר לשפר את התאימות עם מצב ריבוי חלונות ו-MD באפליקציות שמשתמשות onPause() במקום onStop() כדי להפסיק לרענן את ממשק המשתמש ואת האינטראקציה עם המשתמש. מה זה אומר?

  • שתי הפעילויות במסך המפוצל ממשיכות.
  • כל הפעילויות הגלויות למעלה במצב פריסה גמישה מופעלות מחדש.
  • ניתן להמשיך פעילויות בכמה מסכים בו-זמנית.

איור 1. המשך צפייה בכמה משחקים בו-זמנית במכשיר מתקפל

איור 2. קורות חיים מרובות במצב מחשב

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

  • במסך מפוצל ממוזער (עם מרכז האפליקציות בצד), הפעילות העליונה לא מתחדשת כי אי אפשר להתמקד בו.
  • במצב 'תמונה בתוך תמונה', הפעילות לא מתחדשת כי אי אפשר להתמקד בה.
  • פעילויות שמכסות פעילויות שקופות אחרות באותה מקבץ.

הגישה הזו מציינת לאפליקציות שפעילות יכולה לקבל קלט משתמש במצב RESUMED בלבד. לפני Android 10, הפעילויות יכולות גם לקבל קלט במצב PAUSED (לדוגמה, אפשר לנסות לגעת את שתי הפעילויות במסך מפוצל בו-זמנית במכשיר שמערכת ההפעלה שלו היא Android 9).

כדי לשמר את האות להמשיך מגרסאות קודמות של Android (וגם כדי להודיע מתי האפליקציות צריכות לקבל גישה לגישה בלעדית או ל-Singleton משאבים), Android 10 כולל קריאה חוזרת (callback) חדשה:

Activity#onTopResumedActivityChanged(boolean onTop)

במהלך ההפעלה, הקריאה החוזרת (callback) הזו היא בין Activity#onResume() ו-Activity#onPause(). הקריאה החוזרת היא אופציונלית ואפשר לדלג עליה, כך שפעילות יכולה לעבור מ-RESUMED למצב PAUSED מבלי להפוך לחלק העליון במערכת. לדוגמה, במצב ריבוי חלונות. הקריאה החוזרת היא אופציונלית, ולכן היא לא חלק מהפעילות מחזור חיים וצריך להשתמש בו לעיתים רחוקות.

הפעילות הקודמת שהתחדשה בתדירות הגבוהה ביותר מקבלת ומסיימת את הביצוע של onTopResumedActivity(false) לפני הפעילות הבאה שמתחדשת מקבל onTopResumedActivity(true), אלא אם הפעילות הקודמת נדרש יותר מדי זמן לטיפול בקריאת השיטה ומגיע לזמן הקצוב לתפוגה של 500 אלפיות השנייה.

תאימות

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

מספר פעילויות שחזרו על עצמן בתהליך אפליקציה אחד

  • בעיה. ב-Android מגרסה 9 ומטה, רק פעילות אחת במערכת בכל פעם שהוא הופעל מחדש. כל המעברים בין הפעילויות כרוכים בהשהיה של פעילות לפני שתחדשו פעילות אחרת. אפליקציות ומסגרות מסוימות (כמו Flutter, או LocalActivityManager של Android) משתמש בעובדה הזו ומצב החנות לגבי המשך בפעילות סינגלטון.
  • פתרון. ב-Android מגרסה 9 ומטה, אם שתי פעילויות מאותו תהליך מתבצעות שתיהן מתחדשות, המערכת ממשיכה רק את הפעילות שנמצאת ברמה גבוהה יותר בסדר Z. אפליקציות שמטרגטות את Android 10 יכולות לתמוך בכמה פעילויות באותו זמן.

גישה למצלמה בו-זמנית

  • בעיות. הבעיות האלה קיימות גם ב-Android 9 נמוכה יותר. לדוגמה, פעילות במסך מלא ופעילות חוזרת עלולות לאבד את המיקוד של המצלמה מושהית את הפעילות בחלק העליון במצב 'תמונה בתוך תמונה', אבל היא נחשפת יותר באמצעות שימוש נרחב יותר במצבי ריבוי חלונות וריבוי מסכים.
    • בגלל שינויים שבוצעו במצב RESUME, יכול להיות שאפליקציות מנותק מהמצלמה גם במהלך המשך. כדי לפתור את הבעיה, אפליקציות צריך לטפל בניתוק מצלמה מבלי לקרוס. בזמן הניתוק, אפליקציות מקבלות הקריאה החוזרת (callback) מנותקת וכל הקריאות ל-API יתחילו לפעול CameraAccessException
    • האפליקציה resizeableActivity=false לא מבטיחה מצלמה בלעדית גישה כי אפשר לפתוח אפליקציות אחרות שמשתמשות במצלמה במסכים אחרים.
  • פתרונות. המפתחים צריכים לכלול לוגיקה לגבי מתי האפליקציה מנותק מהמצלמה. אם האפליקציה מנותקת מהמצלמה, אמור להיות קריאות חוזרות (callback) זמינות של המצלמה בשעון כדי לנסות להתחבר מחדש ולהמשיך לשימוש במצלמה. נוסף על קריאה חוזרת של CameraManager#AvailabilityCallback#onCameraAvailable(), הוספת את Android 10 CameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged(), שמכסה את המקרה כשהמיקוד (ועדיפות המצלמה) עובר בין פעילויות שחזרו. מפתחי אפליקציות צריכים להשתמש בשני הקריאות החוזרות האלה כדי כדי להבין מתי כדאי לנסות לגשת למצלמה.

קורות חיים מרובות

ב-Android 10, מצב מחזור החיים של הפעילות נקבע לפי החשיפה סדר Z. כדי להבטיח שהמצב הנכון לאחר הרשאת הגישה מתעדכנת פעילות ולהעריך איזה מצב של מחזור חיים רלוונטי, הפעילו את שיטת ActivityRecord#makeActiveIfNeeded() מערכים אחרים מיקומים. ב-Android 10, המשמעות של 'פעיל' היא RESUMED או PAUSED ופועל רק בשני המקרים האלה.

ב-Android 10, מתבצע מעקב נפרד אחר המשך פעילות בכל סטאק במקום במיקום יחיד במערכת. הסיבה לכך היא שכמה ניתן לבצע מעברי פעילות בו-זמנית במצב של ריבוי חלונות. עבור פרטים נוספים: ActivityStack#mInResumeTopActivity.

קריאה חוזרת (callback) של פעילות שנמשכת

אחרי פעולות שעשויות להוביל לשינוי בפעילות מובילה (כמו פעילות) הפעלה, המשך או שינוי בסדר Z), בוצעה הפעלה של ActivityStackSupervisor#updateTopResumedActivityIfNeeded(). הזה הפונקציה בודקת אם הפעילות בחלק העליון ביותר שחודשה ומבצעת את העדכון הדרושים. אם הפעילות הקודמת שנמשכה הכי הרבה לא שוחררה אז נשלחת הודעת איבוד מצב שהתחדש ביותר, והזמן הקצוב לתפוגה הוא תוזמן בצד השרת (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()). דוח של המצב החודשי העליון נשלח לפעילות הבאה אחרי הפעילות הקודמת אחת משחררת את המצב, או כאשר הגיע הזמן הקצוב לתפוגה (ראו שימושים ב:

ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()

נוסף פריט חדש בעסקה מסוג TopResumedActivityChangeItem כדי לדווח ללקוחות על שינויים משמעותיים במצב של המצב, ומנצלת את ארכיטקטורה של ActivityLifecycler מ-Android 9.

המצב האחרון שממש מאוחסן בצד הלקוח, ובכל פעם שהמצב הפעילות עוברת ל-RESUMED או ל-PAUSED, היא גם הפונקציה בודקת אם הקריאה החוזרת של onTopResumedActivityChanged() צריכה להיות הופעלה. כך מתאפשרת הפרדה מסוימת בתקשורת בין מצבים של מחזור החיים ואת המצב המתמשך העליון בין השרת וצד הלקוח.