Android geliştirmede ANR — nedir, nedenleri ve düzeltme yolları

Yazar: IT Sectr Yayınlanma: 2026-03-28 Okuma süresi: 9 dk

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 — bir uygulama 5 saniyeden uzun donduğunda Android sistem uyarısı
  • Ana iş parçacığı (UI iş parçacığı) — engellemenin ANR'ye yol açtığı tek yer
  • InputDispatcher — giriş gecikmesini algılayan ve ANR'yi tetikleyen sistem bileşeni
  • traces.txt — bir cihazda donma nedenini teşhis etmek için anahtar dosya
  • StrictMode — UI iş parçacığında uzun işlemleri algılamak için yerleşik Android aracı

ANR Nedir

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.

ANR'nin Ana Nedenleri

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.

Ana iş parçacığında ağ istekleri

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.

kotlin
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ç
    }
}

UI iş parçacığında yoğun hesaplamalar

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.

Senkronizasyon kilitleri ve Deadlock

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++.

Uzun süreli BroadcastReceiver

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.

Ana iş parçacığında ContentProvider ve SQLite

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 Nasıl Teşhis Edilir

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.

text
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 Nasıl Önlenir

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 — otomatik kontrol

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.

kotlin
if (BuildConfig.DEBUG) {
    StrictMode.ThreadPolicy.Builder()
        .detectDiskReads()
        .detectDiskWrites()
        .detectNetwork()
        .penaltyLog()
        .build()
        .let { StrictMode.setThreadPolicy(it) }
}

Zaman uyumsuz desenler: Coroutines ve RxJava

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.

Üretimde izleme

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.

ANR Tespit Araçları

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ı
StrictModeGeliştirme sırasında algılamaLogcat / Exception
ANR Watchdog (Android Studio)Gerçek zamanlı izlemeThread dump + timeline
Google Play ConsoleToplu istatistiklerANR rate + stack traces
Firebase CrashlyticsÜretim izlemeApplicationExitInfo
adb bugreportTam sistem raporutraces.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 Monitoring

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, Crash'ten nasıl farklıdır?

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.

ANR try-catch ile yakalanabilir mi?

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.

ANR neden bazı cihazlarda görünürken diğerlerinde görünmüyor?

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.

ANR'den önce BroadcastReceiver zaman sınırı nedir?

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.

ANR nadiren oluyorsa ve tekrarlanamıyorsa ne yapmalı?

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

  • ANR — ana iş parçacığı 5 saniyeden uzun bloke olduğunda tetiklenen Android sistem mekanizması
  • Ana iş parçacığı yalnızca UI'yı işlemelidir — diğer tüm işlemler arka plan iş parçacıklarına taşınır
  • ANR teşhisi traces.txt, Google Play Console ve Firebase Crashlytics aracılığıyla yapılır
  • StrictMode gerçek bir cihazda çalıştırmadan geliştirme sırasında potansiyel ANR'leri algılar
  • Coroutines Dispatchers.IO ile — modern Android projelerinde zaman uyumsuz çalışmanın standart yolu
  • BroadcastReceiver'ın 10 saniyeden uzun çalışması için goAsync() veya arka plan kaydedici gerekir
  • Üretimde ANR, Crashlytics ve Android 11 ve üzerinde yerleşik ApplicationExitInfo API'si aracılığıyla izlenir

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.

Projeyi tartış

Ayrıca okuyun