Mulai Android 17, aplikasi yang menargetkan Android 17 (level API 37)
atau yang lebih tinggi akan menerima implementasi
android.os.MessageQueue baru yang bebas kunci. Implementasi baru ini meningkatkan performa dan mengurangi frame yang terlewat, tetapi dapat merusak klien yang merefleksikan metode dan kolom 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 menyebabkan pertentangan kunci; thread utama dapat diblokir oleh thread latar belakang, yang menyebabkan frame terlewat dan UI jank.
Mengurangi 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 implementasi 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.
Selain itu, jika Anda menggunakan beberapa library pengujian populer, Anda harus mengupdate library agar kompatibel dengan implementasi MessageQueue baru.
Espresso
Espresso biasanya digunakan untuk pengujian UI. Library 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
TestLooperManager API, terutama API baru yang diperkenalkan Android 16,
untuk berinteraksi dengan aman dengan Looper tanpa mengandalkan detail implementasi
internal.
Robolectric
Demikian pula, jika Anda menjalankan pengujian unit menggunakan Robolectric, Anda mungkin mengalami masalah jika pengujian 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) yang 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 merupakan build yang dapat di-debug.
Jika aplikasi Anda menargetkan Android 17 (level API 37), perilaku baru akan diaktifkan secara default. Jika Anda melihat perilaku atau error yang tidak terduga setelah menargetkan level API ini, Anda dapat menonaktifkan implementasi baru untuk sementara guna memverifikasi apakah MessageQueue adalah penyebabnya.
Anda dapat mengaktifkan/menonaktifkan 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 lama berbasis kunci, sehingga Anda dapat mengidentifikasi apakah masalah tersebut disebabkan oleh perubahan perilaku antrean pesan.