ANR (Application Not Responding), bir uygulamanın 5 saniye içinde girdiye yanıt vermemesi durumunda Android'de görünen bir sistem bildirimidir. Glitch'lerin (UI blokajı olmayan mantıksal hatalar) ve lag'lerin (tam durma olmadan yavaşlama) aksine, ANR işletim sistemi tarafından kaydedilen kritik bir hatadır: Android, kapatma veya bekleme seçeneğiyle birlikte “Uygulama yanıt vermiyor” diyalogunu gösterir. Android Vitals Documentation'a göre, ANR oranı %0,5'in üzerinde olan uygulamalar Google Play'de daha düşük puan alır ve önerilerden gizlenebilir. Teşhis, /data/anr/traces.txt analizini, StrictMode kullanımını ve ana iplik profillemesini içerir.
Kilit Noktalar
ANR (Application Not Responding), uygulamanın girdiye yanıt vermeyi bırakması durumunda etkinleşen bir Android kullanıcı koruma mekanizmasıdır. Sistem olay işleme süresini izler: BroadcastReceiver onReceive'i 10 saniye içinde tamamlamazsa, Service 20 saniye içinde onCreate'den dönmezse veya ContentProvider 15 saniye içinde yanıt vermezse — Android bir ANR üretir.
Bir ANR oluştuğunda, Android tüm pencerelerin üstünde bir sistem diyalogu gösterir: “Uygulama yanıt vermiyor. Kapatmak mı yoksa beklemek mi istiyorsunuz?” Kullanıcı uygulamayı kapatabilir veya düzelmesini bekleyebilir. ANR'ler sık sık meydana gelirse, kullanıcı uygulamayı kaldırır. Google Play, sıralama algoritmalarında ANR oranını (ANR'li oturumların yüzdesi) dikkate alır.
iOS'ta sistem diyaloglu olan bir ANR eşdeğeri yoktur. Bunun yerine Apple, 0x8badf00d çıkış koduyla süreci sonlandıran Watchdog'u kullanır. Kullanıcı bir diyalog görmez — uygulama ana ekrana kapanır. Bu, Android'de ANR'yi kullanıcı için daha belirgin hale getirir ancak sisteme daha fazla teşhis bilgisi sağlar.
ANR, sistem dört bileşen türünden biri için bir zaman aşımı izlediğinde oluşur. Her bileşenin kendi zaman sınırı vardır.
BroadcastReceiver ana iplikte çalıştırılır. onReceive senkron bir ağ isteği başlatırsa, veritabanına uzun bir yazma yaparsa veya bir kilit beklerse — 10 saniye içinde bir ANR oluşur. Çözüm: arka plan işleme için goAsync() ve WorkManager kullanın. Tipik bir senaryo, FCM'den Push bildirimi almak ve Room'a senkron olarak kaydetmektir.
Service.onCreate ve Service.onStartCommand 20 saniye sınırına sahiptir. Hizmet, ana iplikte ağır bir başlatma (kütüphane yükleme, ağdan yapılandırma okuma) başlatırsa — ANR kaçınılmazdır. Arka planda garantili yürütme için IntentService (eski) veya WorkManager kullanın.
ContentProvider.onCreate, Application.onCreate'dan önce çalıştırılır ve 15 saniye sınırına sahiptir. Sağlayıcı veritabanı geçişi yaparsa, sözlükler yüklerse veya ağdan SDK başlatırsa — bu, uygulama başlatmada ANR'ye neden olur. Çözüm: tembel başlatma, ağır işlemleri WorkManager'a aktarma.
Android, sistem günlüklerinden özel kütüphanelere kadar ANR analizi için çeşitli araçlar sağlar.
Her ANR'de Android, tüm uygulama ipliklerinin yığın dökümünü içeren /data/anr/traces.txt dosyasını kaydeder. “main” ipliğini bulun — yığındaki son yöntem nedeni gösterir. Tipik desenler: Thread.sleep(), InputStream.read(), BinderProxy.transact(). Dosyayı cihazdan çıkarmak için süper kullanıcı ayrıcalıklarıyla adb kullanın.
Firebase Crashlytics, ANR'leri otomatik olarak toplar ve izlerle birlikte gösterge tablosunda gösterir. Android 11+ için ANR raporları, ana ipliğin tam yığını içerir. Entegrasyon, bir bağımlılık eklemeyi ve Application.onCreate'da FirebaseApp'i başlatmayı gerektirir.
Android Studio'daki CPU Profiler, uygulama izlerini kaydetmenize ve hangi yöntemlerin CPU süresi tükettiğini görmenize olanak tanır. “Record with method traces” özelliğini etkinleştirin ve ANR'ye neden olan senaryoyu yeniden oluşturun. Zaman çizelgesi, donma anında ana iplikte hangi yöntemlerin çalıştığını gösterecektir.
Android'de ANR toplama için Firebase Crashlytics entegrasyonu örneği:
class App : Application() {
override fun onCreate() {
super.onCreate()
FirebaseApp.initializeApp(this)
FirebaseCrashlytics.getInstance()
.setCrashlyticsCollectionEnabled(true)
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
}
}
ANR'yi düzeltmek, tüm uzun işlemleri ana iplikten arka plan ipliklerine taşımak anlamına gelir. Her bileşen türü için belirli tekniklere bakalım.
WorkManager, arka plan çalışması için Google tarafından önerilen çözümdür. Cihaz durumunu dikkate alarak bir arka plan ipliğinde görev yürütmeyi garanti eder. Service'in aksine, WorkManager ana ipliği bloke etmez ve uygulama yeniden başlatmalarına karşı dayanıklıdır. BroadcastReceiver için goAsync() kullanın ve PendingResult'u WorkManager'a iletin.
Tüm ağ isteklerini, veritabanı işlemlerini ve dosya G/Ç işlemlerini Dispatchers.IO ile çalıştırın. Ana iplik yalnızca UI'yı güncellemelidir. Activity yok edildiğinde otomatik coroutine iptali için viewModelScope kullanın. Herhangi bir bağlamda runBlocking()'den kaçının — mevcut ipliği senkron olarak bloke eder.
ContentProvider yavaş başlatma yapıyorsa, tembel yükleme mekanizması kullanın: hemen veri döndüren bir sağlayıcı oluşturun ve WorkManager aracılığıyla gecikmeli olarak ağır başlatmayı başlatın. Bu, sistemin gecikmelere en duyarlı olduğu uygulama başlatmada ANR'yi önler.
Android'de goAsync ile BroadcastReceiver'ın doğru kullanımı örneği:
class FcmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val pendingResult = goAsync()
WorkManager.getInstance(context!!)
.enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
pendingResult.finish()
}
}
ANR'lerle mücadele etmenin en iyi yolu, araçlar ve mimari kararlar aracılığıyla geliştirme sırasında bunları önlemektir.
Etkinleştirilmiş detectNetwork() ve detectDiskReads()/detectDiskWrites() politikalarıyla StrictMode, geliştirme sırasında potansiyel ANR'leri belirler. Debug yapılarında penaltyDeath ayarlayın — herhangi bir ihlal anında çökmeye neden olur ve geliştirici commit'ten önce sorunu görür.
Firebase Performance, anahtar işlemlerin yürütme süresini izler ve hangi senaryoların ANR eşiğini aştığını gösterir. Her ekran ve ağ isteği için özel izler ayarlayın. Yürütme süresi 3 saniyeyi aşarsa — optimizasyon gerektiren potansiyel bir ANR'dir.
Yavaş koşulları simüle edin: iOS veya Android Emulator'da Network Link Conditioner kullanarak ağ hızını sınırlayın. Yavaş bellek emülasyonuyla disk okumalarını yavaşlatın. ANR genellikle tam da bu koşullarda ortaya çıkar; hızlı geliştirici cihazlarında görünmezler.
Sıkça Sorulan Sorular
Android, ana iplikteki olay işleme süresini açıkça izler ve bir ANR diyalogu gösterir. iOS, 10–20 saniyeden fazla donduğunda uygulamayı zorla kapatan Watchdog'u kullanır. ANR, birden çok bileşenin (BroadcastReceiver, Service) sıkı zaman aşımlarına sahip olduğu Android mimarisinin bir özelliğidir.
Android 11+'da adb shell dumpsys dropbox --print data_app_anr aracılığıyla ANR dökümünü alabilirsiniz. Android 10 ve altında, kök erişimi olmadan /data/anr/traces.txt'ye erişilemez. Firebase Crashlytics kullanın — Android 11+ için ANR raporlarını otomatik olarak toplar.
Google Play, ANR oranının %0,5'in altında olmasını önerir — 1000 oturum başına en fazla 5 ANR. Oranı %1'in üzerinde olan bir uygulama, Google Play Console'da bir uyarı alır ve önerilerden gizlenebilir. İdeal olarak, ANR oranı %0,1'in altında olmalıdır.
Coroutine'nin kendisi ipliği bloke etmez. Ancak bir coroutine içinde ana iplikte runBlocking çalıştırırsanız veya coroutine Dispatchers.Main ile başlatılır ve uzun bir CPU işlemi yaparsa — bu ANR'ye neden olur. G/Ç için Dispatchers.IO ve hesaplamalar için Dispatchers.Default kullanın.
“Slow Network” profiliyle Android Emulator kullanın veya ana iplikte Thread.sleep(6000) çağıran bir test yazın. Uygulamayı Debug üzerinden başlatın ve 5 saniye sonra ANR diyalogunu göreceksiniz. logcat'te iz ile birlikte bir ANR kaydı göründüğünü doğrulayın.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun