Mulai Android 17, aplikasi yang menargetkan Android 17
atau yang lebih tinggi menerima penerapan bebas kunci baru dari
android.os.MessageQueue. Implementasi baru ini meningkatkan performa dan mengurangi frame yang terlewat, tetapi dapat merusak klien yang mencerminkan kolom dan metode pribadi MessageQueue.
Android 17 memperkenalkan perombakan signifikan pada cara kerja Looper dan
Handler, dengan menulis ulang class MessageQueue yang mendasarinya.
Sejak rilis pertama sistem operasi Android, MessageQueue mengandalkan
satu kunci untuk mengelola antrean tugas thread utama. Desain ini sering kali menyebabkan pertentangan kunci; thread utama dapat diblokir oleh thread latar belakang, yang menyebabkan frame terputus dan jank UI.
Memitigasi dampak
Aplikasi Anda mungkin terpengaruh oleh perubahan ini jika aplikasi atau dependensinya mengandalkan
refleksi runtime untuk melihat ke dalam MessageQueue. Hindari penggunaan refleksi runtime untuk memeriksa MessageQueue.
Dengan penerapan lama, developer terkadang mengakses kolom pribadi seperti MessageQueue.mMessages untuk memeriksa pesan yang tertunda. Dengan implementasi bebas kunci yang baru, struktur data internal telah berubah sepenuhnya.
Untuk mempertahankan kompatibilitas biner, Android 17 mempertahankan kolom mMessages, tetapi dalam
implementasi baru, kolom ini selalu null, terlepas dari apakah
ada pesan dalam antrean atau tidak.
Selain itu, jika Anda menggunakan beberapa library pengujian populer, Anda harus mengupdate library agar kompatibel dengan penerapan MessageQueue baru.
Espresso
Espresso biasanya digunakan untuk pengujian UI. Pustaka Espresso perlu mengetahui kapan thread utama tidak ada aktivitas untuk menegaskan status UI dengan benar. Versi Espresso sebelumnya mengandalkan teknik refleksi yang tidak lagi kompatibel dengan MessageQueue bebas kunci.
Tindakan
Update ke Espresso 3.7.0 atau yang lebih baru. Versi ini menggunakan API
TestLooperManager, khususnya API baru yang diperkenalkan Android 16,
untuk berinteraksi dengan Looper secara aman tanpa mengandalkan detail
implementasi internal.
Robolectric
Demikian pula, jika Anda menjalankan pengujian unit menggunakan Robolectric, Anda mungkin mengalami masalah jika pengujian Anda mengandalkan mode Looper lama.
Tindakan
Update ke Robolectric 4.17 atau yang lebih baru. Jika Anda menggunakan @LooperMode(LEGACY),
Anda harus memigrasikan pengujian ke @LooperMode(PAUSED) baru. Lihat
panduan migrasi Robolectric untuk mengetahui informasi selengkapnya.
Menguji perilaku
Anda dapat menguji aplikasi dengan perubahan perilaku di Android 17 tanpa mengupdate
targetSDK dengan menjalankan perintah berikut:
adb am compat enable USE_NEW_MESSAGEQUEUE <your-package-name>
Perintah ini mengaktifkan MessageQueue bebas kunci di aplikasi Anda, jika aplikasi tersebut adalah build yang dapat di-debug.
Jika aplikasi Anda menargetkan Android 17, perilaku baru diaktifkan
secara default. Jika Anda melihat perilaku atau error yang tidak terduga setelah menargetkan level API ini, Anda dapat menonaktifkan penerapan baru untuk sementara guna memverifikasi apakah MessageQueue adalah penyebabnya.
Anda dapat mengalihkan perubahan menggunakan salah satu dari dua opsi:
Dengan menjalankan perintah ADB berikut:
adb am compat disable USE_NEW_MESSAGEQUEUE <your-package-name>
Tindakan ini akan mengembalikan aplikasi Anda ke implementasi berbasis kunci lama, sehingga Anda dapat mengidentifikasi apakah masalah tersebut disebabkan oleh perubahan perilaku antrean pesan.