תמיכה במצב ריבוי חלונות

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

איור 1. הצגת שתי אפליקציות זו לצד זו במצב מסך מפוצל.

הוראות למשתמשים על גישה למצב מסך מפוצל בטלפונים זמינות במאמר הצגת שתי אפליקציות בו-זמנית בטלפון Pixel.

תכונות ריבוי חלונות ספציפיות לגרסה

חוויית המשתמש בריבוי חלונות תלויה בגרסת Android ובסוג המכשיר:

  • ב-Android 7.0 (רמת API‏ 24) הוצג מצב מסך מפוצל במכשירים עם מסך קטן ומצב תמונה בתוך תמונה במכשירים נבחרים.

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

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

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

      אתם יכולים להגדיר איך האפליקציה שלכם מטפלת במצב מרובה חלונות על ידי ציון המידות המינימליות המותרות של הפעילות. אפשר גם להשבית את מצב ריבוי החלונות באפליקציה על ידי הגדרת resizeableActivity="false" כדי לוודא שהמערכת תמיד תציג את האפליקציה במסך מלא.

  • Android 8.0 (רמת API‏ 26) מרחיבה את מצב 'תמונה בתוך תמונה' למכשירים עם מסך קטן.

  • ב-Android 12 (רמת API‏ 31), מצב מרובה חלונות הוא התנהגות רגילה.

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

    • במסכים קטנים (סיווג גודל החלון קומפקטי), המערכת בודקת את minWidth ואת minHeight של פעילות כדי לקבוע אם הפעילות יכולה לפעול במצב מרובה חלונות. אם resizeableActivity="false", האפליקציה לא תפעל במצב ריבוי חלונות, ללא קשר לרוחב ולגובה המינימליים.

  • Android 16 (רמת API‏ 36) מבטל את ההגבלות על כיוון המסך, יחס הגובה-רוחב ושינוי הגודל.

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

      כדי לדעת איך להחריג משחקים מהשינויים ב-Android 16, אפשר לעיין בחריגים בנושא כיוון האפליקציה, יחס הגובה-רוחב והיכולת לשנות את גודל החלון.

מצב מסך מפוצל

כדי להפעיל את מצב המסך המפוצל, המשתמשים צריכים:

  1. פותחים את המסך 'אחרונים'.
  2. החלקה כדי להציג אפליקציה
  3. לוחצים על סמל האפליקציה בסרגל הכותרת של האפליקציה.
  4. בוחרים באפשרות התפריט של המסך המפוצל.
  5. בוחרים אפליקציה אחרת מתוך המסך 'אחרונות', או סוגרים את המסך 'אחרונות' ומפעילים אפליקציה אחרת.

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

הפעלת חלון סמוך

אם האפליקציה שלכם צריכה לגשת לתוכן באמצעות intent, אתם יכולים להשתמש ב-FLAG_ACTIVITY_LAUNCH_ADJACENT כדי לפתוח את התוכן בחלון סמוך של מסך מפוצל.

FLAG_ACTIVITY_LAUNCH_ADJACENT הופיע ב-Android 7.0 (רמת API‏ 24) כדי לאפשר לאפליקציות שפועלות במצב מסך מפוצל להפעיל פעילויות בחלון הסמוך.

ב-Android 12L (רמת API‏ 32) ומעלה, ההגדרה של הדגל הורחבה כדי לאפשר לאפליקציות שפועלות במסך מלא להפעיל את מצב המסך המפוצל ואז להפעיל פעילויות בחלון הסמוך.

כדי להפעיל פעילות סמוכה, משתמשים ב-FLAG_ACTIVITY_LAUNCH_ADJACENT בשילוב עם FLAG_ACTIVITY_NEW_TASK, לדוגמה:

fun openUrlInAdjacentWindow(url: String) {
    Intent(Intent.ACTION_VIEW).apply { data = Uri.parse(url)
       addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT or Intent.FLAG_ACTIVITY_NEW_TASK)
    }.also { intent -> startActivity(intent) }
}

מחזור החיים של פעילות במצב ריבוי חלונות

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

המשך צפייה

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

התכונה 'הפעלה של כמה סרטונים' זמינה גם במכשירים נבחרים עם Android 9 (API ברמה 28). כדי להפעיל את התכונה 'המשך צפייה בכמה תכנים' במכשירי Android 9, צריך להוסיף את המטא-נתונים הבאים למניפסט:

<meta-data android:name="android.allow_multiple_resumed_activities" android:value="true" />

כדי לוודא שמכשיר מסוים תומך במטא-נתונים של המניפסט הזה, אפשר לעיין במפרט המכשיר.

‫Android 9

במצב מרובה חלונות ב-Android 9 (רמת API‏ 28) ובגרסאות קודמות, רק הפעילות שהמשתמש קיים איתה אינטראקציה לאחרונה פעילה בכל זמן נתון. הפעילות הזו נחשבת העליונה ביותר, והיא הפעילות היחידה במצב RESUMED. כל הפעילויות הגלויות האחרות הן STARTED אבל לא RESUMED. עם זאת, המערכת נותנת עדיפות גבוהה יותר לפעילויות שגלויות אבל לא הופעלו מחדש, מאשר לפעילויות שלא גלויות. אם המשתמש מקיים אינטראקציה עם אחת מהפעילויות הגלויות, הפעילות הזו ממשיכה, והפעילות שהייתה הכי למעלה עוברת למצב STARTED.

אם יש כמה פעילויות בתהליך פעיל אחד של אפליקציה, הפעילות עם הערך הכי גבוה של z-order ממשיכה, והפעילויות האחרות מושהות.

שינויים בהגדרות

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

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

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

גישה בלעדית למשאבים

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

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

override fun onTopResumedActivityChanged(topResumed: Boolean) {
    if (topResumed) {
        // Top resumed activity.
        // Can be a signal to re-acquire exclusive resources.
    } else {
        // No longer the top resumed activity.
    }
}

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

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

באפליקציות שמשתמשות במצלמה, CameraManager.AvailabilityCallback#onCameraAccessPrioritiesChanged() מספק רמז לכך שעכשיו יכול להיות זמן טוב לנסות לקבל גישה למצלמה. השיטה הזו זמינה החל מ-Android 10 (רמת API‏ 29).

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

איור 2. המצלמה במצב ריבוי חלונות.

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

אחרי שאפליקציה מקבלת קריאה חוזרת (callback) מסוג CameraDevice.StateCallback#onDisconnected(), קריאות חוזרות (callback) עוקבות במכשיר המצלמה יחזירו CameraAccessException.

מדדים של חלונות

ב-Android 11 (רמת API ‏30) הוספו השיטות הבאות WindowManager כדי לספק את הגבולות של אפליקציות שפועלות במצב ריבוי חלונות:

השיטות בספריית Jetpack WindowManager‏ computeCurrentWindowMetrics() ו-computeMaximumWindowMetrics() מציעות פונקציונליות דומה, אבל עם תאימות לאחור עד לרמת API 14.

כדי לקבל מדדים לגבי תצוגות שאינן התצוגה הנוכחית, מבצעים את הפעולות הבאות (כפי שמוצג בקטע הקוד):

  • יצירת הקשר לתצוגה
  • יצירת הקשר של חלון לתצוגה
  • קבלת WindowManager של הקשר החלון
  • קבלת WindowMetrics של אזור התצוגה המקסימלי שזמין לאפליקציה

val windowMetrics = context.createDisplayContext(display)
                           .createWindowContext(WindowManager.LayoutParams.TYPE_APPLICATION, null)
                           .getSystemService(WindowManager::class.java)
                           .maximumWindowMetrics

שיטות שהוצאו משימוש

הוצאנו משימוש את ה-methods ‏DisplaygetSize() ו-getMetrics() ברמת API‏ 30, לטובת ה-methods החדשים WindowManager.

ב-Android 12 (רמת API‏ 31) הוצאו משימוש השיטות Display getRealSize() ו-getRealMetrics(), וההתנהגות שלהן עודכנה כך שתהיה דומה יותר להתנהגות של getMaximumWindowMetrics().

הגדרת מצב ריבוי חלונות

אם האפליקציה מטרגטת את Android 7.0 (רמת API ‏24) ואילך, אפשר להגדיר אם הפעילויות של האפליקציה תומכות במצב מרובה חלונות ואיך הן תומכות בו. אפשר להגדיר מאפיינים במניפסט כדי לשלוט גם בגודל וגם בפריסה. הגדרות המאפיינים של פעילות הבסיס חלות על כל הפעילויות במקבץ המשימות שלה. לדוגמה, אם לפעילות הבסיס יש android:resizeableActivity="true", אז אפשר לשנות את הגודל של כל הפעילויות במצבור המשימות. במכשירים גדולים יותר, כמו Chromebook, יכול להיות שהאפליקציה תפעל בחלון שניתן לשינוי גודל גם אם תציינו android:resizeableActivity="false". אם השינוי הזה גורם לבעיות באפליקציה, אפשר להשתמש במסננים ב-Google Play כדי להגביל את הזמינות של האפליקציה במכשירים כאלה.

ב-Android 12 (רמת API‏ 31), מצב ריבוי חלונות מוגדר כברירת מחדל. במסכים גדולים (גודל החלון בינוני או מורחב), כל האפליקציות פועלות במצב ריבוי חלונות, ללא קשר להגדרת האפליקציה. במסכים קטנים, המערכת בודקת את ההגדרות של פעילות minWidth, minHeight ו-resizeableActivity כדי לקבוע אם אפשר להפעיל את הפעילות במצב מרובה חלונות.

resizeableActivity

כדי להפעיל או להשבית את מצב ריבוי החלונות עבור API ברמה 30 ומטה, צריך להגדיר את המאפיין הזה באלמנט <activity> או <application> במניפסט:

<application
  android:name=".MyActivity"
  android:resizeableActivity=["true" | "false"] />;

אם המאפיין הזה מוגדר לערך true, אפשר להפעיל את הפעילות במצב מסך מפוצל ובמצב חלונות במחשב. אם המאפיין מוגדר לערך false, הפעילות לא תומכת במצב מרובה חלונות. אם הערך הוא False והמשתמש מנסה להפעיל את הפעילות במצב מרובה חלונות, הפעילות תופסת את המסך כולו.

אם האפליקציה שלכם מטרגטת רמת API‏ 24 ומעלה, אבל לא ציינתם ערך למאפיין הזה, ערך ברירת המחדל של המאפיין הוא true.

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

  • מסכים גדולים (סיווג גודל החלון בינוני או מורחב): כל האפליקציות תומכות במצב ריבוי חלונות. המאפיין מציין אם אפשר לשנות את הגודל של פעילות. אם resizeableActivity="false", האפליקציה מועברת למצב תאימות כשצריך להתאים אותה למידות המסך.
  • מסכים קטנים (סיווג גודל חלון קומפקטי): אם resizeableActivity="true" והרוחב והגובה המינימליים של הפעילות עומדים בדרישות של מצב מרובה חלונות, הפעילות תומכת במצב מרובה חלונות. אם הערך הוא resizeableActivity="false", הפעילות לא תומכת במצב ריבוי חלונות, ללא קשר לרוחב ולגובה המינימליים של הפעילות.

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

אם אתם מפתחים משחק, במאמר כיוון האפליקציה, יחס הגובה-רוחב והיכולת לשנות את גודל החלון מוסבר איך להחריג את המשחק שלכם מהשינויים ב-Android 16 (רמת API‏ 36).

supportsPictureInPicture

מגדירים את המאפיין הזה בצומת <activity> במניפסט כדי לציין אם הפעילות תומכת במצב 'תמונה בתוך תמונה'.

<activity
  android:name=".MyActivity"
  android:supportsPictureInPicture=["true" | "false"] />

configChanges

כדי לטפל בעצמכם בשינויים בהגדרות של חלונות מרובים, למשל כשמשתמש משנה את הגודל של חלון, מוסיפים את המאפיין android:configChanges לצומת <activity> של מניפסט האפליקציה עם הערכים הבאים לפחות:

<activity
  android:name=".MyActivity"
  android:configChanges="screenSize | smallestScreenSize
      | screenLayout | orientation" />

אחרי שמוסיפים את android:configChanges, הפעילות והקטעים מקבלים קריאה חוזרת אל onConfigurationChanged() במקום להיהרס וליצור מחדש. לאחר מכן תוכלו לעדכן את הצפיות באופן ידני, לטעון מחדש משאבים ולבצע פעולות אחרות לפי הצורך.

<layout>

ב-Android 7.0 (רמת API‏ 24) ומעלה, רכיב המניפסט <layout> תומך בכמה מאפיינים שמשפיעים על אופן הפעולה של פעילות במצב מרובה חלונות:

  • android:defaultHeight, android:defaultWidth: גובה ורוחב ברירת המחדל של הפעילות כשהיא מופעלת במצב של שינוי דינמי של חלונות במחשב.

  • android:gravity: המיקום הראשוני של הפעילות כשהיא מופעלת במצב חלונות במחשב. אפשר לעיין בערכים המתאימים בכיתה Gravity.

  • android:minHeight, android:minWidth: הגובה המינימלי והרוחב המינימלי של הפעילות במצב מסך מפוצל ובמצב שינוי דינמי של חלונות במחשב. אם המשתמש מזיז את הקו המפריד במצב מסך מפוצל כדי להקטין את הפעילות מתחת לגודל המינימלי שצוין, המערכת חותכת את הפעילות לגודל שהמשתמש מבקש.

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

<activity android:name=".MyActivity">
    <layout android:defaultHeight="500dp"
          android:defaultWidth="600dp"
          android:gravity="top|end|..."
          android:minHeight="450dp"
          android:minWidth="300dp" />
</activity>

מצב ריבוי חלונות בזמן ריצה

החל מ-Android 7.0, המערכת מציעה פונקציונליות לתמיכה באפליקציות שיכולות לפעול במצב מרובה חלונות.

תכונות שמושבתות במצב ריבוי חלונות

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

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

המערכת מתעלמת משינויים במאפיין android:screenOrientation.

שאילתות והתקשרות חוזרת במצב ריבוי חלונות

המחלקות Activity מציעות את השיטות הבאות לתמיכה במצב מרובה חלונות:

  • isInMultiWindowMode(): מציין אם הפעילות מתבצעת במצב מרובה חלונות.

  • isInPictureInPictureMode(): מציין אם הפעילות היא במצב תמונה בתוך תמונה.

  • onMultiWindowModeChanged(): המערכת קוראת לשיטה הזו בכל פעם שהפעילות עוברת למצב מרובה חלונות או יוצאת ממנו. המערכת מעבירה את השיטה ערך של true אם הפעילות נכנסת למצב ריבוי חלונות, או false אם הפעילות יוצאת ממצב ריבוי חלונות.

  • onPictureInPictureModeChanged(): המערכת קוראת לשיטה הזו בכל פעם שהפעילות עוברת למצב 'תמונה בתוך תמונה' או יוצאת ממנו. המערכת מעבירה לשיטה ערך True אם הפעילות נכנסת למצב 'תמונה בתוך תמונה', או ערך False אם הפעילות יוצאת ממצב 'תמונה בתוך תמונה'.

הכיתה Fragment חושפת גרסאות של רבות מהשיטות האלה. לדוגמה, Fragment.onMultiWindowModeChanged().

מצב תמונה בתוך תמונה

כדי להעביר פעילות למצב 'תמונה בתוך תמונה', קוראים ל-enterPictureInPictureMode(). לשיטה הזו אין השפעה אם המכשיר לא תומך במצב 'תמונה בתוך תמונה'. מידע נוסף זמין במאמר בנושא הוספת סרטונים באמצעות תמונה בתוך תמונה (PiP).

פעילויות חדשות במצב ריבוי חלונות

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

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

ב-API ברמה 30 ומטה, אם מפעילים פעילות בתוך מחסנית משימות, הפעילות מחליפה את הפעילות במסך ומקבלת בירושה את כל המאפיינים שלה בחלונות מרובים. אם רוצים להפעיל את הפעילות החדשה כחלון נפרד במצב ריבוי חלונות, צריך להפעיל אותה במצבור משימות חדש.

ב-Android 12 (רמת API‏ 31) אפשר לפצל את חלון המשימה של האפליקציה בין כמה פעילויות. אתם קובעים איך הפעילויות של האפליקציה יוצגו – במסך מלא, זו לצד זו או אחת מעל השנייה – על ידי יצירת קובץ הגדרות XML או על ידי ביצוע קריאות ל-API של Jetpack WindowManager.

גרירה ושחרור

המשתמשים יכולים לגרור ולשחרר נתונים מפעילות אחת לפעילות אחרת כשהפעילויות מוצגות במסך משותף. (לפני Android 7.0, משתמשים יכלו רק לגרור ולשחרר נתונים בתוך פעילות אחת). כדי להוסיף במהירות תמיכה בקבלת תוכן שנוסף בשיטת Drag and Drop, אפשר לעיין ב-API‏ DropHelper. הוראות מפורטות לגבי גרירה ושחרור זמינות במאמר הפעלת גרירה ושחרור.

כמה מופעים במקביל

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

ב-Android 12 (רמת API‏ 31) ומעלה, אפשר להפעיל שני מופעים של פעילות זה לצד זה בחלון המשימה זהה בהטמעה של פעילות.

אם רוצים לאפשר למשתמשים להפעיל עוד מופע של האפליקציה ממרכז האפליקציות או מסרגל המשימות, צריך להגדיר את android:resizeableActivity="true" במניפסט של פעילות ההפעלה, ולא להשתמש במצב הפעלה שמונע הפעלה של כמה מופעים. לדוגמה, אפשר ליצור מופע של פעילות singleInstancePerTask כמה פעמים במשימות שונות כשמוגדר FLAG_ACTIVITY_MULTIPLE_TASK או FLAG_ACTIVITY_NEW_DOCUMENT.

ב-Android מגרסה 15 (API ברמה 35) ואילך, אפשר להשתמש ב-PROPERTY_SUPPORTS_MULTI_INSTANCE_SYSTEM_UI כדי להצהיר על תמיכה בריבוי מופעים. המאפיין הוא אות מפורש לממשק המשתמש של המערכת לחשוף אמצעי בקרה למשתמש כדי ליצור כמה מופעים של האפליקציה. המאפיין לא תלוי במצב ההפעלה, אבל צריך להשתמש בו רק כשמצב ההפעלה של פעילות או אפליקציה תואם למאפיין, למשל כשמצב ההפעלה הוא לא singleInstance.

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

אימות במצב ריבוי חלונות

גם אם האפליקציה שלכם מטרגטת רמת API ‏24 ומעלה, כדאי לבדוק איך היא מתנהגת במצב מרובה חלונות, למקרה שמשתמש ינסה להפעיל אותה במצב מרובה חלונות במכשיר עם Android 7.0 ומעלה.

בדיקת מכשירים

מכשירים עם Android 7.0 (רמת API‏ 24) ומעלה תומכים במצב מרובה חלונות.

רמת API ‏23 ומטה

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

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

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

רמות API‏ 24 עד 30

אם האפליקציה שלכם מטרגטת רמות API‏ 24 עד 30 ולא משביתה את התמיכה בריבוי חלונות, צריך לאמת את ההתנהגות הבאה במצבי חלונות של מסך מפוצל ושל שולחן עבודה:

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

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

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

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

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

רמת API ‏31 ומעלה

אם האפליקציה מטרגטת לרמת API‏ 31 ומעלה, והרוחב המינימלי והגובה המינימלי של הפעילות הראשית קטנים או שווים לממדים המתאימים של אזור התצוגה הזמין, צריך לוודא שכל ההתנהגויות שמופיעות ברמות API‏ 24 עד 30 מתקיימות.

רשימת משימות לבדיקה

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

  • איך עוברים למצב ריבוי חלונות ויוצאים ממנו

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

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

  • מבצעים כמה פעולות שינוי גודל ברצף מהיר. מוודאים שהאפליקציה לא קורסת או גורמת לדליפת זיכרון. כלי Memory Profiler ב-Android Studio מספק מידע על השימוש בזיכרון של האפליקציה (ראו בדיקת השימוש בזיכרון של האפליקציה באמצעות Memory Profiler).

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

התמיכה בריבוי חלונות מושבתת

ברמות API‏ 24 עד 30, אם השבתתם את התמיכה בריבוי חלונות על ידי הגדרת android:resizeableActivity="false", אתם צריכים להפעיל את האפליקציה במכשיר עם Android 7.0 עד 11 ולנסות להעביר את האפליקציה למצב מסך מפוצל ולמצב חלונות של שולחן עבודה. מוודאים שכשהאפליקציה נפתחת, היא נשארת במצב מסך מלא.

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

מידע נוסף על תמיכה בריבוי חלונות ב-Android זמין במאמרים הבאים: