راهنمای تغییر رفتار MessageQueue

از Android 17، برنامه‌هایی که Android 17 (سطح میانای برنامه‌سازی کاربردی ۳۷) یا بالاتر را هدف قرار می‌دهند، پیاده‌سازی جدیدی از android.os.MessageQueue بدون قفل دریافت می‌کنند. پیاده‌سازی جدید عملکرد را بهبود می‌بخشد و فریم‌های ازدست‌رفته را کاهش می‌دهد، اما ممکن است مشتریانی را که به MessageQueue فیلدها و روش‌های خصوصی ارجاع می‌دهند خراب کند.

Android 17 با بازنویسی کلاس MessageQueue زیربنایی، بازنگری قابل‌توجهی در نحوه عملکرد Looper و Handler معرفی می‌کند. از زمان اولین انتشار سیستم‌عامل Android،‏ MessageQueue برای مدیریت صف وظایف رشته اصلی به یک قفل تکی متکی بوده است. این طراحی اغلب باعث رقابت قفل می‌شد؛ رشته اصلی ممکن بود توسط رشته پس‌زمینه مسدود شود، که منجر به افت فریم و لرزش واسط کاربر می‌شد.

کاهش تأثیر

اگر برنامه شما یا وابستگی‌های آن برای نگاه کردن به داخل MessageQueue به بازتاب زمان اجرا متکی باشد، ممکن است تحت تأثیر این تغییر قرار گیرد. از بازتاب زمان اجرا برای بازرسی MessageQueue استفاده نکنید.

با پیاده‌سازی قدیمی، توسعه‌دهندگان گاهی به فیلدهای خصوصی مثل MessageQueue.mMessages دسترسی پیدا می‌کردند تا پیام‌های معلقه را بررسی کنند. با پیاده‌سازی جدید بدون قفل، ساختارهای داده داخلی کاملاً تغییر کرده‌اند. برای حفظ سازگاری دودویی، Android 17 فیلد mMessages را نگه می‌دارد، اما در پیاده‌سازی جدید، این فیلد همیشه تهی است، صرف‌نظر از اینکه پیامی در صف وجود داشته باشد یا نه.

علاوه‌براین، اگر از برخی کتابخانه‌های آزمایشی محبوب استفاده می‌کنید، باید کتابخانه‌هایتان را به‌روز کنید تا با پیاده‌سازی جدید MessageQueue سازگار شوند.

اسپرسو

Espresso معمولاً برای آزمایش واسط کاربر استفاده می‌شود. کتابخانه Espresso باید بداند چه زمانی رشته اصلی بیکار است تا بتواند به‌درستی وضعیت میانای کاربر را تأیید کند. نسخه‌های قبلی Espresso به تکنیک‌های بازتابی متکی بودند که دیگر با MessageQueue بدون قفل سازگار نیستند.

کنش

به Espresso 3.7.0 یا جدیدتر به‌روزرسانی کنید. این نسخه از TestLooperManager API، به‌ویژه 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 متوجه رفتار غیرمنتظره یا ازکارافتادن شدید، می‌توانید به‌طور موقت پیاده‌سازی جدید را غیرفعال کنید تا بررسی کنید که آیا MessageQueue علت آن است یا نه.

می‌توانید بااستفاده از یکی از این دو گزینه، تغییر را فعال یا غیرفعال کنید:

  1. منوی تغییرات سازگاری برنامه در گزینه‌های توسعه‌دهندگان.

  2. با اجرای فرمان ADB زیر:

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

این کار برنامه‌تان را به پیاده‌سازی قدیمی مبتنی بر قفل برمی‌گرداند و به شما امکان می‌دهد تشخیص دهید که آیا مشکل ناشی از تغییر رفتار صف پیام بوده است یا نه.