החל מ-Android 17, אפליקציות שמטרגטות ל-Android 17 (רמת API 37) או גרסה חדשה יותר מקבלות הטמעה חדשה ללא נעילה של android.os.MessageQueue. ההטמעה החדשה משפרת את הביצועים ומפחיתה את מספר הפריימים שהוחמצו, אבל עלולה לגרום לתקלות בלקוחות שמשקפים שדות ושיטות פרטיים של MessageQueue.
ב-Android 17 יש שינוי משמעותי באופן הפעולה של Looper ו-Handler, על ידי שכתוב של המחלקה MessageQueue הבסיסית.
מאז הגרסה הראשונה של מערכת ההפעלה Android, MessageQueue הסתמכה על נעילה אחת כדי לנהל את תור המשימות של ה-thread הראשי. העיצוב הזה גרם לעיתים קרובות לתחרות על נעילה. ה-thread הראשי נחסם על ידי thread ברקע, מה שגרם לפריימים שהוחמצו ולתקלות בממשק המשתמש.
הפחתת ההשפעה
השינוי הזה עשוי להשפיע על האפליקציה אם היא או יחסי התלות שלה מסתמכים על רפלקציה בזמן ריצה כדי להציץ בתוך MessageQueue. אל תשתמשו ב-runtime reflection כדי לבדוק את MessageQueue.
בהטמעה הקודמת, מפתחים ניגשו לפעמים לשדות פרטיים כמו MessageQueue.mMessages כדי לבדוק הודעות בהמתנה. בגרסה החדשה, שבה אין נעילה, מבני הנתונים הפנימיים השתנו לחלוטין.
כדי לשמור על תאימות בינארית, השדה mMessages נשאר ב-Android 17, אבל בהטמעה החדשה השדה הזה תמיד ריק, גם אם יש הודעות בתור.
בנוסף, אם אתם משתמשים בספריות בדיקה פופולריות, תצטרכו לעדכן את הספריות כך שיהיו תואמות להטמעה החדשה של MessageQueue.
אספרסו
בדרך כלל משתמשים ב-Espresso לבדיקות של ממשק המשתמש. ספריית Espresso צריכה לדעת מתי ה-thread הראשי לא פעיל כדי להצהיר בצורה נכונה על מצב ממשק המשתמש. גרסאות קודמות של 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 ללא נעילה באפליקציה, אם מדובר ב-build שניתן לבצע בו ניפוי באגים.
אם האפליקציה מטרגטת ל-Android 17 (רמת API 37), ההתנהגות החדשה מופעלת כברירת מחדל. אם אתם מבחינים בהתנהגות לא צפויה או בקריסות אחרי הטירגוט לרמת ה-API הזו, אתם יכולים להשבית באופן זמני את ההטמעה החדשה כדי לבדוק אם MessageQueue היא הגורם לכך.
אתם יכולים להפעיל או להשבית את השינוי באחת משתי דרכים:
מריצים את פקודת ה-ADB הבאה:
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
הפעולה הזו מחזירה את האפליקציה להטמעה הקודמת שמבוססת על נעילה, ומאפשרת לכם לזהות אם הבעיה נבעה משינוי בהתנהגות של תור ההודעות.