ANR (Application Not Responding), bir uygulama 5 saniyeden uzun süre kullanıcı girişine yanıt vermeyi durdurduğunda ortaya çıkan bir Android sistem bildirimidir. Android Developers'a göre, ana neden ana iş parçacığındaki uzun işlemlerin dokunma işlemeyi ve UI oluşturmayı engellemesidir. Duyarlı uygulamalar oluşturmak için her Android geliştiricisinin ANR mekanizmalarını anlaması gereklidir.
Önemli Noktalar
ANR (Application Not Responding), bir uygulama kullanıcı girişine yanıt vermeyi durdurduğunda ortaya çıkan Android işletim sistemi iletişim kutusudur. Sistem, InputDispatcher aracılığıyla olay işleme süresini izler: bir dokunma veya düğmeye basma 5 saniye içinde işlenmezse, Android uygulamayı kapatma veya bekleme seçeneği sunan bir iletişim kutusu gösterir.
ANR mekanizması, donmuş uygulamalardan kullanıcı deneyimini korur. Android, bir uygulamanın tüm sistemi engellemesine izin vermez — masaüstü işletim sistemlerinin aksine, mobil platform olay işleme süresini zorla sınırlar. BroadcastReceiver'ın 10 saniyelik bir sınırı vardır ve ön plan hizmetinin 20 saniyelik sınırı vardır.
ANR, kodda bir istisna DEĞİLDİR — Linux süreç düzeyinde bir sistem mekanizmasıdır. Android sürece SIGQUIT sinyali gönderir ve ardından sistem tüm iş parçacıklarının çağrı yığınını traces.txt dosyasına kaydeder. Geliştirici ANR'yi bir catch istisnası olarak değil, uygulama yeniden başlatıldıktan sonra bir rapor olarak alır. Android 11+'da, ApplicationExitInfo API'si, ANR dahil olmak üzere süreç sonlandırma nedenini programlı olarak almayı sağlar — bu, manuel traces.txt ayrıştırması olmadan istatistik toplamayı basitleştirir.
Beş kategori işlem, Android uygulamalarında tutarlı bir şekilde ANR'ye yol açar. Her biri ana iş parçacığını engeller ve sistemin giriş olaylarını ve ekran yeniden çizimini işlemesini önler.
UI iş parçacığında yürütülen senkron HTTP istekleri, acemi geliştiriciler arasında ANR'nin en yaygın nedenidir. Bir sunucuya hızlı bir istek bile 1–3 saniye sürebilir ve kötü bir bağlantıda — 30 saniye veya daha fazla. Android, API 11'den itibaren ana iş parçacığında ağ işlemlerini açıkça yasaklar ve NetworkOnMainThreadException fırlatır.
Zaman uyumsuz çağrılar için Coroutines veya RxJava kullanın. Dispatchers.IO dağıtıcısına sahip coroutine'ler isteği bir arka plan iş parçacığında yürütür ve sonucu Dispatchers.Main aracılığıyla ana iş parçacığına iletir. Bu, ağ işlemleri tarafından UI iş parçacığı engellemesini tamamen ortadan kaldırır.
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // arka plan işlemi
}
updateUI(result) // ana iş parçacığında sonuç
}
}
Büyük veri dizilerini işleme, JSON veya XML ayrıştırma, doğrudan ana iş parçacığında bitmap ile çalışma — ANR'nin ikinci en sık nedenidir. Olay döngüsüne dönmeden UI iş parçacığının 300 milisaniye sürekli çalışması bile oluşturmada gözle görülür bir gecikmeye neden olur ve 5 saniyelik eşik ANR olarak kaydedilir.
WorkManager ve arka plan hizmetleri, ağır hesaplamaları ana iş parçacığından taşımak için tasarlanmıştır. UI'yı engellemeden verileri parçalar halinde iletmek için AsyncTask (kullanımdan kaldırıldı), ListenableFuture veya Kotlin Flow kullanın.
Deadlock, iki iş parçacığı kilit tuttuğunda ve birbirini beklediğinde oluşur. İş parçacıklarından biri ana iş parçacığıysa, sistem tam 5 saniye sonra ANR'yi kaydeder. UI iş parçacığından çağrılan Thread.join(), CountDownLatch.await() ve synchronized blokları engelleme riski taşır.
Ana iş parçacığında herhangi bir engelleyici işlemden kaçının. Synchronized yerine ConcurrentHashMap kullanın; Thread.join() yerine async/await ile coroutine'ler kullanın. Bu kural Android'deki her dil için geçerlidir: Java, Kotlin veya JNI aracılığıyla C++.
BroadcastReceiver varsayılan olarak ana iş parçacığında çalışır. onReceive() 10 saniyeden uzun süre meşgulse, Android ANR gösterir. onReceive içinde veritabanından veya ağdan veri yüklemek, donmaya giden garantili bir yoldur.
Bir arka plan iş parçacığına geçmek için BroadcastReceiver içinde goAsync() kullanın veya getBackgroundBroadcastReceiver() ile registerReceiver kullanın. Bu, UI'yı engellemeden olayları işlemeye izin verir.
ContentProvider'a ağır sorgular veya UI iş parçacığında SQLite ile doğrudan çalışma — daha az belirgin ancak yaygın bir ANR nedenidir. Veritabanı geçişi veya binlerce kaydın toplu eklenmesi sırasında, yürütme süresi 5 saniyelik sınırı aşabilir.
Tüm veritabanı işlemlerini, suspend işlevleriyle Room kullanarak arka plan iş parçacıklarına taşıyın. Room, sorgunun ana iş parçacığında yürütülmediğini otomatik olarak kontrol eder ve ihlal durumunda bir istisna fırlatır.
ANR teşhisi normal istisnaların hata ayıklamasından farklıdır — ANR'yi bir try-catch bloğunda yakalayamazsınız. Ana bilgi kaynağı, Android'in donma anında oluşturduğu traces.txt dosyasıdır.
traces.txt, ANR anında tüm uygulama iş parçacıklarının çağrı yığınını içerir. Gerçek bir cihazdan dosyayı okumak için, son tüm ANR'leri içeren tam bir sistem raporu toplayan adb bugreport komutunu çalıştırın. Bir öykünücü için dosya /data/anr/traces.txt adresinde bulunur. Çağrı yığını, engelleme anında ana iş parçacığında hangi yöntemin yürütüldüğünü gösterir.
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt
Google Play Console, toplu raporlar ve hata sıklıkları içeren ANR & Crash bölümünü sağlar. Her ANR için çağrı yığını ve cihaz istatistikleri gösterilir: model, Android sürümü, bölge. Bu, belirli cihazlara veya sistem sürümlerine bağlı ANR'leri tanımlamayı sağlar.
Android Studio 2021'den itibaren profil oluşturucuda ANR Watchdog içerir. Ana iş parçacığı bir eşik süresinden uzun süre yanıt vermezse otomatik olarak iş parçacığı dökümlerini kaydeder. Araç, bir olay zaman çizelgesi gösterir: hangi işlemler başlatıldı, hangi yöntemler yürütüldü ve engelleme hangi aşamada gerçekleşti.
ANR'nin önlenmesi temel bir kurala dayanır: ana iş parçacığı yalnızca UI olaylarını işlemelidir. 16 milisaniyeden (bir kare süresi) uzun herhangi bir işlem bir arka plan iş parçacığında yürütülmelidir.
StrictMode, geliştirme sırasında potansiyel ANR'leri algılamak için yerleşik bir Android aracıdır. Disk ve ağ işlemleri için bayraklarla Application.onCreate() içinde etkinleştirin. İhlal durumunda, StrictMode bir istisna fırlatır veya logcat'e yazar.
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
Kotlin Coroutines — modern Android uygulamalarında zaman uyumsuz çalışmanın standart yoludur. Temel yaklaşım: G/Ç işlemleri Dispatchers.IO'da yürütülür, sonuç UI güncellemeleri için Dispatchers.Main'e iletilir. Flow benzeri senaryolar için CPU yoğun görevlerde Dispatchers.Default kullanın.
RxJava eski projelerde popüler olmaya devam ediyor. subscribeOn(Schedulers.io()) ve observeOn(AndroidSchedulers.mainThread()) — ANR'yi önlemek için minimum settir. Ana kural aynıdır: hiçbir Observable veya Flowable ana iş parçacığından veri yaymamalıdır.
Firebase Crashlytics, SDK sürüm 18.4.0'dan itibaren ANR izlemeyi kutudan çıktığı gibi destekler. Android 11+ için Crashlytics, tam sonlandırma nedenini sağlayan sistem API'si ApplicationExitInfo'yu kullanır: ANR, Crash veya sistem tarafından öldürme. Bağlamsal analiz için ekran ve durum parametreleriyle özel anahtarları etkinleştirin.
Beş araç, ANR ile çalışmanın tüm aşamalarını kapsar: bir iş istasyonunda hata ayıklamadan üretimde izlemeye kadar. Her araç kendi görevini çözer ve farklı senaryolar için veri sağlar.
| Araç | Amaç | Veri formatı |
|---|---|---|
| StrictMode | Geliştirme sırasında algılama | Logcat / Exception |
| ANR Watchdog (Android Studio) | Gerçek zamanlı izleme | Thread dump + timeline |
| Google Play Console | Toplu istatistikler | ANR rate + stack traces |
| Firebase Crashlytics | Üretim izleme | ApplicationExitInfo |
| adb bugreport | Tam sistem raporu | traces.txt + logcat + dmesg |
Her aracın kendi nişi vardır: StrictMode erken aşamalarda bariz ihlalleri yakalar, Crashlytics kullanıcılar arasında gerçek ANR sıklığını gösterir ve adb bugreport karmaşık durumlar için en eksiksiz resmi sağlar. Tam kapsama için bunları birleştirin.
Firebase Performance, UI iş parçacığı yanıt süresini izler ve şüpheli derecede uzun işlemler için otomatik olarak izlemeler oluşturur. Ana iş parçacığı 500 ms'den uzun süre bloke olursa, Performance, neden olan yöntemin adıyla özel bir izleme kaydeder. Bu, kullanıcı katılımı olmadan ve kritik hale gelmeden önce ANR senaryolarını algılamayı sağlar.
Firebase Crashlytics ile entegrasyon tam bir resim sağlar: Performance ANR öncesi yavaşlamaları gösterir ve Crashlytics donmayı gösterir. Firebase Console'da ANR oranı %0.1'in üzerinde olduğunda uyarılar ayarlayın ve toplu kullanıcı şikayetlerinden önce yeni sorunlar hakkında bildirimler alırsınız.
Sıkça Sorulan Sorular
ANR, uygulamanın yanıt vermediği ancak bellekte kaldığı bir donmadır. Crash, süreçten çıkışla birlikte tam anormal sonlandırmadır. ANR, sistem veya kullanıcı bir yanıt beklerse “atalatılabilir”, oysa Crash her zaman uygulamayı sonlandırır.
Hayır. ANR bir Java/Kotlin istisnası değil, süreç düzeyinde bir sistem sinyalidir (SIGQUIT). Bir geliştirici bunu uygulama kodunda işleyemez. ANR'ye yanıt vermenin tek yolu, yeniden başlatmadan sonra raporları analiz etmektir.
Cihaz performansı, Android sürümü, CPU yükü ve arka plan işlemlerinin sayısı ANR olasılığını etkiler. Zayıf cihazlarda aynı işlem 2–3 kat daha uzun sürebilir ve 5 saniyelik sınırı aşabilir.
Normal bir BroadcastReceiver için onReceive()'de 10 saniye. Ön plan hizmetleri için sınır 20 saniyedir ve ContentProvider için — açık bir sınır yoktur, ancak ana iş parçacığını 5 saniyeden uzun bloke etmek yine de ANR'ye neden olur.
Tüm hata ayıklama yapılarında StrictMode'u etkinleştirin, Firebase Crashlytics aracılığıyla izleme ekleyin ve ANR oluştuğunda adb bugreport kullanın. Düzensiz ANR'ler genellikle yarış koşulları veya belirli ağ durumlarıyla ilgilidir.
Ö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