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

איור 1. פעילות מקבילה במכשיר מתקפל

איור 2. פעילות מקבילה במצב שולחן עבודה
פעילויות יכולות להיות במצב PAUSED אם אי אפשר להתמקד בהן או אם הן מוסתרות חלקית, למשל:
- במסך מפוצל ממוזער (עם מרכז האפליקציות בצד), הפעילות העליונה לא ממשיכה כי אי אפשר להתמקד בה.
- במצב'תמונה בתוך תמונה', הפעילות לא מתחדשת כי אי אפשר להתמקד בה.
- כשהפעילויות מכוסות על ידי פעילויות שקופות אחרות באותו מחסנית.
הגישה הזו מציינת לאפליקציות שפעילות יכולה לקבל קלט ממשתמש רק במצב RESUMED. לפני Android 10, פעילויות יכלו לקבל קלט גם במצב PAUSED (לדוגמה, נסו לגעת בשתי הפעילויות במסך המפוצל בו-זמנית במכשיר עם Android 9).
כדי לשמור על האות resumed מגרסאות קודמות של Android (וכדי להעביר מידע על המועד שבו אפליקציות צריכות לקבל גישה למשאבים מסוג exclusive-access או singleton), Android 10 כולל קריאה חוזרת (callback) חדשה:
Activity#onTopResumedActivityChanged(boolean onTop)
כשמפעילים את הקריאה החוזרת הזו, היא מתבצעת בין Activity#onResume() לבין Activity#onPause(). הקריאה החוזרת הזו היא אופציונלית ואפשר לדלג עליה, כך שפעילות יכולה לעבור ממצב RESUMED למצב PAUSED בלי להפוך לעליונה ביותר במערכת. לדוגמה, במצב ריבוי חלונות.
הקריאה החוזרת הזו היא אופציונלית, ולכן היא לא חלק ממחזור החיים של Activity, ומומלץ להשתמש בה לעיתים רחוקות.
הפעילות הקודמת שהופעלה מחדש מקבלת את onTopResumedActivity(false) ומסיימת את ההרצה שלו לפני שהפעילות הבאה שהופעלה מחדש מקבלת את onTopResumedActivity(true), אלא אם הפעילות הקודמת אורכת יותר מדי זמן לטיפול בהפעלת method ומגיעה לזמן הקצוב לתפוגה של 500 אלפיות השנייה.
תאימות
כדי לשמור על תאימות כשמטמיעים את התכונה 'פעילות מקבילה', כדאי להשתמש בפתרונות הבאים.
כמה פעילויות שחודשו בתהליך אחד של אפליקציה
- בעיה. ב-Android מגרסה 9 ומטה, רק פעילות אחת במערכת מושהית בכל פעם. כל המעברים בין פעילויות כוללים השהיה של פעילות אחת לפני שממשיכים בפעילות אחרת. חלק מהאפליקציות ומסגרות העבודה (כמו Flutter או LocalActivityManager של Android) משתמשות בעובדה הזו ושומרות את המצב של הפעילות שהופעלה מחדש בסינגלטונים.
- פתרון. ב-Android 9 ובגרסאות קודמות, אם שתי פעילויות מאותו תהליך מופעלות מחדש, המערכת מפעילה מחדש רק את הפעילות שהמיקום שלה גבוה יותר בסדר Z. אפליקציות שמטרגטות את Android 10 יכולות לתמוך בהפעלה מחדש של כמה פעילויות בו-זמנית.
גישה למצלמה בו-זמנית
- בעיות. הבעיות האלה קיימות גם ב-Android מגרסה 9 ומגרסאות קודמות. לדוגמה, פעילות במסך מלא שהופסקה יכולה לאבד את המיקוד של המצלמה לפעילות מושהית שמוצגת מעליה במצב 'תמונה בתוך תמונה', אבל היא יכולה להיות חשופה יותר אם משתמשים יותר במצבי ריבוי חלונות וריבוי מסכים.
- בגלל שינויים שבוצעו במצב
RESUME, יכול להיות שאפליקציות יתנתקו מהמצלמה גם כשהן ממשיכות לפעול. כדי לפתור את הבעיה, האפליקציות צריכות לטפל בניסיון לנתק את המצלמה בלי לקרוס. כשמתנתקים, האפליקציות מקבלות קריאה חוזרת (callback) של ניתוק, וכל הקריאות ל-API מתחילות להחזירCameraAccessException. resizeableActivity=falseלא מבטיח גישה בלעדית למצלמה, כי אפשר לפתוח אפליקציות אחרות שמשתמשות במצלמה במסכים אחרים.
- בגלל שינויים שבוצעו במצב
- פתרונות. המפתחים צריכים לכלול לוגיקה למקרים שבהם אפליקציה מנותקת מהמצלמה. אם אפליקציה מנותקת מהמצלמה, היא צריכה לעקוב אחרי קריאות חוזרות (callback) של זמינות המצלמה כדי לנסות להתחבר מחדש ולהמשיך להשתמש במצלמה. בנוסף ל-callback הקיים
CameraManager#AvailabilityCallback#onCameraAvailable(), ב-Android 10 נוסףCameraManager#AvailabilityCallback#onCameraAccessPrioritiesChanged(), שמתייחס למקרה שבו המיקוד (והעדיפות של המצלמה) עובר בין כמה פעילויות שהופעלו מחדש. מפתחי אפליקציות צריכים להשתמש בשתי פונקציות הקריאה החוזרת האלה כדי לקבוע מתי כדאי לנסות לקבל גישה למצלמה.
פעילות מקבילה
ב-Android 10, מצב מחזור החיים של הפעילות נקבע לפי הנראות והסדר בציר Z. כדי לוודא שהמצב הנכון מוצג אחרי עדכוני החשיפה בפעילות, ולהעריך איזה מצב במחזור החיים רלוונטי, מפעילים את השיטה ActivityRecord#makeActiveIfNeeded() ממיקומים שונים. ב-Android 10, המצב הפעיל הוא RESUMED או PAUSED, והוא פועל רק בשני המקרים האלה.
ב-Android 10, חידוש פעילות מתבצע בנפרד בכל מחסנית במקום במיקום יחיד במערכת. הסיבה לכך היא שבמצבי ריבוי חלונות אפשר לבצע כמה מעברים בין פעילויות בו-זמנית. מידע נוסף זמין במאמר ActivityStack#mInResumeTopActivity.
השיחה החוזרת של הפעילות שהופסקה
אחרי פעולות שיכולות לגרום לשינוי בפעילות העליונה (כמו הפעלה, המשכה או שינוי בסדר Z של פעילות), מופעלת הפונקציה ActivityStackSupervisor#updateTopResumedActivityIfNeeded(). השיטה הזו בודקת אם הפעילות העליונה ביותר שהופסקה השתנתה, ומבצעת את העדכון אם צריך. אם הפעילות הקודמת שהושהתה לא שחררה את המצב שלה, נשלחת אליה הודעה על אובדן המצב שלה ומוגדר פסק זמן בצד השרת (ActivityStackSupervisor#scheduleTopResumedStateLossTimeout()). דוח על המצב של הפעילות שהושהתה נשלח לפעילות הבאה אחרי שהפעילות הקודמת שחררה את המצב שלה, או כשחל פסק זמן (ראו את השימושים הבאים:
ActivityStackSupervisor#scheduleTopResumedActivityStateIfNeeded()
נוסף פריט חדש של TopResumedActivityChangeItem טרנזקציה כדי לדווח ללקוחות על שינויים במצב העליון של הפעלה מחדש, והוא מבוסס על ארכיטקטורת ActivityLifecycler מ-Android 9.
המצב העליון של הפעילות שחודשה מאוחסן בצד הלקוח, ובכל פעם שהפעילות עוברת למצב RESUMED או PAUSED, המערכת גם בודקת אם צריך להפעיל את הקריאה החוזרת onTopResumedActivityChanged(). ההגדרה הזו מאפשרת הפרדה מסוימת בתקשורת של מצבי מחזור החיים ומצב ההפעלה העליון בין צד השרת לצד הלקוח.