החל מ-Android 17, אפליקציות שמטרגטות את Android 17 (רמת API 37)
או גרסאות חדשות יותר מקבלות הטמעה חדשה ללא נעילה של
android.os.MessageQueue. ההטמעה החדשה משפרת את הביצועים ומפחיתה את מספר הפריימים החסרים, אבל היא עלולה לגרום לשיבוש בלקוחות שמשקפים שדות ושיטות פרטיים.MessageQueue
ב-Android 17 בוצע שינוי משמעותי באופן הפעולה של Looper ושל Handler, על ידי כתיבה מחדש של המחלקה הבסיסית MessageQueue.
מאז הגרסה הראשונה של מערכת ההפעלה Android, MessageQueue הסתמכה על נעילה אחת כדי לנהל את תור המשימות של ה-thread הראשי. העיצוב הזה גרם לעיתים קרובות למחלוקת על נעילה. ה-thread הראשי יכול להיחסם על ידי thread ברקע, מה שמוביל להשמטת פריימים ולבעיות בממשק המשתמש.
צמצום ההשפעה
השינוי הזה עשוי להשפיע על האפליקציה שלכם אם היא או התלויות שלה מסתמכות על runtime reflection כדי להציץ לתוך MessageQueue. אל תשתמשו בהשתקפות בזמן ריצה כדי לבדוק את MessageQueue.
ביישום הקודם, מפתחים לפעמים ניגשו לשדות פרטיים כמו MessageQueue.mMessages כדי לבדוק הודעות בהמתנה. ביישום החדש שאינו כולל נעילה, המבנים הפנימיים של הנתונים השתנו לחלוטין.
כדי לשמור על תאימות בינארית, Android 17 שומרת על השדה mMessages, אבל בהטמעה החדשה השדה הזה תמיד מכיל ערך null, גם אם יש הודעות בתור וגם אם לא.
בנוסף, אם אתם משתמשים בספריות בדיקה פופולריות מסוימות, תצטרכו לעדכן את הספריות כדי שהן יהיו תואמות להטמעה החדשה של MessageQueue.
אספרסו
Espresso משמשת בדרך כלל לבדיקות של ממשק המשתמש. ספריית Espresso צריכה לדעת מתי ה-Thread הראשי בלי פעילות כדי לבצע טענת נכוֹנוּת (assertion) נכונה של מצב ממשק המשתמש. גרסאות קודמות של Espresso הסתמכו על טכניקות השתקפות שכבר לא תואמות ל-MessageQueue ללא נעילה.
פעולה
צריך לעדכן לגרסה Espresso 3.7.0 או לגרסה חדשה יותר. בגרסה הזו נעשה שימוש ב-API TestLooperManager, במיוחד בממשקי API חדשים שהוצגו ב-Android 16, כדי ליצור אינטראקציה בטוחה עם Looper בלי להסתמך על פרטים פנימיים של ההטמעה.
Robolectric
באופן דומה, אם מריצים בדיקות יחידה באמצעות Robolectric, יכול להיות שתיתקלו בבעיות אם הבדיקות שלכם מסתמכות על מצב Looper מדור קודם.
פעולה
מעדכנים לגרסה Robolectric 4.17 ואילך. אם אתם משתמשים ב-@LooperMode(LEGACY), תצטרכו להעביר את הבדיקות שלכם ל-@LooperMode(PAUSED) החדש. מידע נוסף זמין במדריך להעברת נתונים של Robolectric.
בדיקת ההתנהגות
אתם יכולים לבדוק את האפליקציה עם השינוי בהתנהגות ב-Android 17 בלי לעדכן את targetSDK על ידי הפעלת הפקודה הבאה:
adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>
הפקודה הזו מפעילה את MessageQueue באפליקציה, אם היא גרסה שניתן לבצע בה ניפוי באגים.
אם האפליקציה מטרגטת את Android 17 (רמת API 37), ההתנהגות החדשה מופעלת כברירת מחדל. אם אתם מבחינים בהתנהגות לא צפויה או בקריסות אחרי טירגוט רמת ה-API הזו, אתם יכולים להשבית באופן זמני את ההטמעה החדשה כדי לוודא ש-MessageQueue היא הסיבה לכך.
אפשר להחליף בין האפשרויות באמצעות אחת משתי האפשרויות הבאות:
מריצים את פקודת ה-ADB הבאה:
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
הפעולה הזו תחזיר את האפליקציה להטמעה מדור קודם שמבוססת על נעילה, ותאפשר לכם לזהות אם הבעיה נבעה משינוי בהתנהגות של תור ההודעות.