MessageQueue davranış değişikliğiyle ilgili kılavuz

Android 17'den itibaren, Android 17 (API düzeyi 37) veya sonraki sürümleri hedefleyen uygulamalar, android.os.MessageQueue için yeni bir kilitsiz uygulama alır. Yeni uygulama, performansı artırır ve kaçırılan kareleri azaltır ancak MessageQueue özel alanlarını ve yöntemlerini yansıtan istemcileri bozabilir.

Android 17, temel MessageQueue sınıfını yeniden yazarak Looper ve Handler sınıflarının işleyişinde önemli değişiklikler yapıyor. Android işletim sisteminin ilk sürümünden bu yana MessageQueue, ana iş parçacığının görev sırasını yönetmek için tek bir kilide dayanıyordu. Bu tasarım genellikle kilit çekişmesine neden oluyordu. Ana iş parçacığı, arka plan iş parçacığı tarafından engellenebiliyor, bu da karelerin düşmesine ve kullanıcı arayüzünde takılmalara yol açıyordu.

Etkiyi azaltma

Uygulamanız veya bağımlılıkları MessageQueue'ye göz atmak için çalışma zamanı yansımasını kullanıyorsa bu değişiklikten etkilenebilir. MessageQueue öğesini incelemek için çalışma zamanı yansıması kullanmaktan kaçının.

Eski uygulamada geliştiriciler, bekleyen mesajları incelemek için bazen MessageQueue.mMessages gibi özel alanlara erişiyordu. Yeni kilitsiz uygulama ile dahili veri yapıları tamamen değişti. Android 17, ikili program uyumluluğunu korumak için mMessages alanını korur ancak yeni uygulamada bu alan, sırada mesaj olup olmadığına bakılmaksızın her zaman null olur.

Ayrıca, bazı popüler test kitaplıklarını kullanıyorsanız kitaplıklarınızı yeni MessageQueue uygulamasıyla uyumlu olacak şekilde güncellemeniz gerekir.

Espresso

Espresso, genellikle kullanıcı arayüzü testleri için kullanılır. Espresso kitaplığının, kullanıcı arayüzü durumunu doğru şekilde onaylamak için ana iş parçacığının ne zaman boşta olduğunu bilmesi gerekir. Espresso'nun önceki sürümleri, artık kilitsiz MessageQueue ile uyumlu olmayan yansıma tekniklerini kullanıyordu.

İşlem

Espresso 3.7.0 veya sonraki bir sürüme güncelleyin. Bu sürüm, dahili uygulama ayrıntılarına bağlı kalmadan Looper ile güvenli bir şekilde etkileşim kurmak için TestLooperManager API'yi, özellikle de Android 16'da kullanıma sunulan yeni API'leri kullanır.

Robolectric

Benzer şekilde, Robolectric kullanarak birim testleri çalıştırıyorsanız testleriniz eski Looper modunu kullanıyorsa sorunlarla karşılaşabilirsiniz.

İşlem

Robolectric 4.17 veya sonraki bir sürüme güncelleyin. @LooperMode(LEGACY) kullanıyorsanız testlerinizi yeni @LooperMode(PAUSED)'e taşımanız gerekir. Daha fazla bilgi için Robolectric'in geçiş rehberine bakın.

Davranışı test etme

Aşağıdaki komutu çalıştırarak targetSDK değerini güncellemeden uygulamanızı Android 17'deki davranış değişikliğiyle test edebilirsiniz:

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

Bu komut, hata ayıklanabilir bir derlemeyse uygulamanızda kilitsiz MessageQueue özelliğini etkinleştirir.

Uygulamanız Android 17'yi (API düzeyi 37) hedefliyorsa yeni davranış varsayılan olarak etkinleştirilir. Bu API düzeyini hedefledikten sonra beklenmedik davranışlar veya kilitlenmeler fark ederseniz nedenin MessageQueue olup olmadığını doğrulamak için yeni uygulamayı geçici olarak devre dışı bırakabilirsiniz.

Değişikliği iki seçenekten birini kullanarak açıp kapatabilirsiniz:

  1. Geliştirici Seçenekleri'ndeki Uygulama Uyumluluğu Değişiklikleri menüsü.

  2. Aşağıdaki ADB komutunu çalıştırarak:

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

Bu işlem, uygulamanızı eski, kilit tabanlı uygulamaya geri döndürür ve sorunun mesaj sırası davranış değişikliğinden kaynaklanıp kaynaklanmadığını belirlemenize olanak tanır.