הנחיות לשינוי התנהגות של MessageQueue

החל מ-Android 17, אפליקציות שמטרגטות את Android 17 ומעלה מקבלות הטמעה חדשה ללא נעילה של 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 הראשי לא פעיל כדי לבצע בדיקה נכונה של מצב ממשק המשתמש. בגרסאות קודמות של 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 הזו, אתם יכולים להשבית באופן זמני את ההטמעה החדשה כדי לוודא ש-MessageQueue היא הסיבה לכך.

אפשר להחליף בין האפשרויות באמצעות אחת משתי האפשרויות הבאות:

  1. התפריט שינויים בתאימות האפליקציה באפשרויות למפתחים.

  2. מריצים את פקודת ה-ADB הבאה:

    adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
    

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