Android inkişafında ANR — nədir, səbəbləri və düzəltmə yolları

Müəllif: IT Sectr Dərc olunub: 2026-03-28 Oxuma vaxtı: 9 dəq

ANR (Application Not Responding) — bu, tətbiq istifadəçi girişinə 5 saniyədən artıq cavab vermədikdə ortaya çıxan Android sistem bildirişidir. Android Developers məlumatına görə, əsas səbəb toxunuşların işlənməsini və interfeysin renderini bloklayan əsas axındakı uzun əməliyyatlardır. ANR mexanizmlərini anlamaq hər bir Android tərtibatçısı üçün cavabdeh tətbiqlər yaratmaq üçün vacibdir.

Əsas məqamlar

  • ANR — tətbiq 5 saniyədən artıq donduqda Android sistem xəbərdarlığı
  • Əsas axın (UI axını) — bloklanmanın ANR-yə apardığı yeganə yer
  • InputDispatcher — giriş gecikməsini qeyd edən və ANR başladan sistem komponenti
  • traces.txt — cihazda donma səbəbinin diaqnozu üçün əsas fayl
  • StrictMode — UI axınında uzun əməliyyatları aşkarlamaq üçün Android daxili aləti

ANR nədir

ANR (Application Not Responding) — bu, tətbiq istifadəçi girişinə cavab verməyi dayandırdıqda Android əməliyyat sisteminin görünən dialoq qutusudur. Sistem InputDispatcher vasitəsilə hadisələrin işlənmə müddətini izləyir: əgər toxunuş və ya düymə basılması 5 saniyə ərzində işlənməzsə, Android tətbiqi bağlamaq və ya gözləmək təklifi ilə dialoq göstərir.

ANR mexanizmi istifadəçi təcrübəsini donmuş tətbiqlərdən qoruyur. Android bir tətbiqin bütün sistemi bloklamasına icazə vermir — Desktop ƏS-lərdən fərqli olaraq, mobil platforma hadisələrin işlənmə müddətini məcburi məhdudlaşdırır. BroadcastReceiver 10 saniyə, foreground xidməti isə 20 saniyə limitinə malikdir.

ANR kodda istisna (exception) DEYİL — bu, Linux prosesləri səviyyəsində sistem mexanizmidir. Android prosesə SIGQUIT siqnalı göndərir, bundan sonra sistem bütün axınların çağırış stack-larını traces.txt faylında saxlayır. Tərtibatçı ANR-ni catch-istisnası kimi deyil, tətbiq yenidən başladıqdan sonra hesabat kimi alır. Android 11+-da ApplicationExitInfo API-si meydana çıxdı ki, bu da prosesin bitmə səbəbini, o cümlədən ANR-ni proqramlı şəkildə əldə etməyə imkan verir — bu, traces.txt-ni əl ilə pars etmədən statistika toplamağı asanlaşdırır.

ANR-nin əsas səbəbləri

Beş kateqoriya əməliyyat Android tətbiqlərində ANR-yə sabit şəkildə gətirib çıxarır. Onların hər biri əsas axını bloklayır, sistemə giriş hadisələrini emal etməyə və ekranı yenidən çəkməyə mane olur.

Əsas axında şəbəkə sorğuları

Sinxron HTTP sorğuları UI axınında yerinə yetirilir — bu, başlanğıc tərtibatçılarda ANR-nin ən çox yayılmış səbəbidir. Hətta sürətli server sorğusu 1–3 saniyə çəkə bilər, zəif bağlantıda isə 30 saniyə və daha çox. Android API 11-dən etibarən əsas axında şəbəkə əməliyyatlarını açıq şəkildə qadağan edir, NetworkOnMainThreadException atır.

Asinxron çağırışlar üçün Coroutines və ya RxJava istifadə edin. Dispatchers.IO dispetçeri olan korutinlər sorğunu fon axınında yerinə yetirir, nəticəni isə Dispatchers.Main vasitəsilə əsas axına ötürür. Bu, UI axınının şəbəkə əməliyyatları ilə bloklanmasını tamamilə aradan qaldırır.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // fon əməliyyatı
        }
        updateUI(result) // əsas axında nəticə
    }
}

UI axınında intensiv hesablamalar

Böyük məlumat massivlərinin işlənməsi, JSON və ya XML pars etmə, bitmap ilə birbaşa əsas axında iş — ANR-nin tezliyə görə ikinci səbəbi. Hətta 300 millisaniyəlik fasiləsiz UI axını işi hadisə dövrünə qayıtmadan nəzərə çarpan render gecikməsinə səbəb olur, 5 saniyəlik hədd isə ANR kimi qeydə alınır.

WorkManager və fon xidmətləri ağır hesablamaları əsas axından çıxarmaq üçün nəzərdə tutulub. UI-ni bloklamadan məlumatları hissə-hissə ötürmək üçün AsyncTask (köhnəlmiş), ListenableFuture və ya Kotlin Flow istifadə edin.

Sinkronizasiya bloklanmaları və Deadlock

Deadlock iki axın bloklanmaları saxlayıb bir-birini gözlədikdə yaranır. Əgər axınlardan biri əsas axındırsa, sistem dəqiq 5 saniyədən sonra ANR qeydə alır. UI axınından çağırılan Thread.join(), CountDownLatch.await() və synchronized blokları bloklanma riski daşıyır.

Əsas axında hər hansı bloklayıcı əməliyyatlardan çəkinin. synchronized əvəzinə ConcurrentHashMap, Thread.join() əvəzinə async/await ilə korutinlərdən istifadə edin. Bu qayda Android-də istənilən dil üçün keçərlidir: Java, Kotlin və ya JNI vasitəsilə C++.

BroadcastReceiver-in uzun işi

BroadcastReceiver susmaya görə əsas axında işləyir. Əgər onReceive() 10 saniyədən artıq məşğuldursa, Android ANR göstərir. onReceive daxilində verilənlər bazasından və ya şəbəkədən məlumat yükləmək donmaya zəmanətli yoldur.

BroadcastReceiver daxilində fon axınına keçmək üçün goAsync() və ya getBackgroundBroadcastReceiver() ilə registerReceiver istifadə edin. Bu, UI-ni bloklamadan hadisələri emal etməyə imkan verir.

Əsas axında ContentProvider və SQLite

UI axınında ContentProvider-ə ağır sorğular və ya birbaşa SQLite ilə iş — daha az aşkar, lakin tez-tez rast gəlinən ANR səbəbidir. Verilənlər bazasının miqrasiyası və ya minlərlə qeydin toplu daxil edilməsi zamanı icra müddəti 5 saniyəlik həddi keçə bilər.

Bütün verilənlər bazası əməliyyatlarını suspend-funksiyaları ilə Room vasitəsilə fon axınlarına köçürün. Room avtomatik olaraq sorğunun əsas axında yerinə yetirilmədiyini yoxlayır və pozuntu halında istisna atır.

ANR necə diaqnoz edilir

ANR diaqnozu adi istisnaların aradan qaldırılmasından fərqlənir — ANR-ni try-catch-də tuta bilməzsiniz. Əsas məlumat mənbəyi Android-in donma anında yaratdığı traces.txt faylıdır.

traces.txt ANR anında tətbiqin bütün axınlarının çağırış stack-larını ehtiva edir. Həqiqi cihazdan faylı oxumaq üçün son vaxtlardakı bütün ANR-lər daxil olmaqla tam sistem hesabatını toplayan adb bugreport əmrini icra edin. Emulyator üçün fayl /data/anr/traces.txt ünvanında mövcuddur. Çağırış stack-i bloklanma anında əsas axında hansı metodun icra olunduğunu göstərir.

text
adb bugreport bugreport.zip
unzip -p bugreport.zip "*traces*" > traces.txt

Google Play Console toplanmış hesabatlar və xəta tezlikləri ilə ANR & Crash bölməsini təmin edir. Hər ANR üçün çağırış stack-i və cihazlara görə statistika göstərilir: model, Android versiyası, region. Bu, konkret cihazlardan və ya sistem versiyalarından asılı olan ANR-ləri aşkar etməyə imkan verir.

Android Studio 2021-ci ildən profilerdə ANR Watchdog ehtiva edir. Əsas axın hədd vaxtından artıq cavab vermədikdə avtomatik olaraq axın dump-ını qeyd edir. Alət hadisələrin vaxt xəttini göstərir: hansı əməliyyatlar işə salınıb, hansı metodlar icra olunub və bloklanma hansı mərhələdə baş verib.

ANR-nin qarşısını necə almaq olar

ANR profilaktikası bir əsas qaydaya əsaslanır: əsas axın yalnız UI hadisələrini emal etməlidir. 16 millisaniyədən (bir kadrın vaxtı) artıq davam edən hər hansı əməliyyat fon axınında yerinə yetirilməlidir.

StrictMode — avtomatik yoxlama

StrictMode — inkişaf mərhələsində potensial ANR-ləri aşkar etmək üçün Android daxili aləti. Onu disk və şəbəkə əməliyyatları üçün bayraqlarla Application.onCreate() daxilində aktivləşdirin. Pozuntu halında StrictMode istisna atır və ya logcat-ə yazır.

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

Asinxron nümunələr: Coroutines və RxJava

Kotlin Coroutines — müasir Android tətbiqlərində asinxron işin standart üsuludur. Əsas qəbul: giriş-çıxış əməliyyatları Dispatchers.IO-da yerinə yetirilir, nəticə UI yeniləməsi üçün Dispatchers.Main-ə ötürülür. Flow ssenariləri üçün CPU intensiv tapşırıqlar üçün Dispatchers.Default istifadə edin.

RxJava köhnə layihələrdə populyar olaraq qalır. ANR-nin qarşısını almaq üçün minimal dəst subscribeOn(Schedulers.io()) və observeOn(AndroidSchedulers.mainThread()) təşkil edir. Eyni qayda: heç bir Observable və ya Flowable əsas axından məlumat verməməlidir.

İstehsalatda monitorinq

Firebase Crashlytics SDK 18.4.0 versiyasından ANR monitorinqini qutudan çıxan kimi dəstəkləyir. Android 11+ üçün Crashlytics bitmənin dəqiq səbəbini təmin edən sistem API ApplicationExitInfo-dan istifadə edir: ANR, Crash və ya sistem tərəfindən öldürülmə. Kontekst analizi üçün ekran və vəziyyət parametrləri ilə xüsusi açarları aktivləşdirin.

ANR aşkarlama vasitələri

Beş vasitə ANR ilə işin bütün mərhələlərini əhatə edir: iş stansiyasında debug-dan istehsalatda monitorinqə qədər. Hər bir vasitə öz vəzifəsini həll edir və müxtəlif ssenarilər üçün məlumat təmin edir.

VasitəTəyinatMəlumat formatı
StrictModeİnkişaf mərhələsində aşkarlamaLogcat / Exception
ANR Watchdog (Android Studio)Real vaxtda izləməThread dump + timeline
Google Play ConsoleToplanmış statistikaANR rate + stack traces
Firebase Crashlyticsİstehsalat monitorinqiApplicationExitInfo
adb bugreportTam sistem hesabatıtraces.txt + logcat + dmesg

Hər bir vasitənin öz yeri var: StrictMode erkən mərhələlərdə aşkar pozuntuları tutur, Crashlytics istifadəçilərdə ANR-nin real tezliyini göstərir, adb bugreport isə mürəkkəb hallar üçün maksimum tam mənzərə verir. Tam əhatə üçün onları birləşdirin.

Firebase Performance Monitoring

Firebase Performance UI axınının cavab müddətini izləyir və şübhəli uzun əməliyyatlar üçün avtomatik treyslər yaradır. Əsas axın 500 ms-dən artıq bloklanarsa, Performance günahkar metodun adı ilə xüsusi treys qeyd edir. Bu, ANR ssenarilərini istifadəçi iştirakı olmadan və kritik hala gəlməzdən əvvəl aşkar etməyə imkan verir.

Firebase Crashlytics ilə inteqrasiya tam mənzərə verir: Performance ANR-dən əvvəl yavaşlamaları, Crashlytics isə donma faktını göstərir. Firebase Console-da ANR rate 0.1%-dən yuxarı hadisəyə həyəcan siqnalları qurun və istifadəçilərin kütləvi şikayətlərindən əvvəl yeni problemlər barədə bildirişlər alacaqsınız.

Tez-tez verilən suallar

ANR Crash-dən nə ilə fərqlənir?

ANR — bu donmadır, tətbiq cavab vermir, lakin yaddaşda qalır. Crash — prosesdən çıxmaqla tam qəza başa çatmadır. ANR sağ qala bilər, əgər sistem və ya istifadəçi cavabı gözləyərsə, Crash isə həmişə tətbiqi bitirir.

ANR-ni try-catch ilə tutmaq olarmı?

Xeyr. ANR Java/Kotlin istisnası deyil, proseslər səviyyəsində sistem siqnalıdır (SIGQUIT). Tərtibatçı onu tətbiq kodunda emal edə bilməz. ANR-yə reaksiya verməyin yeganə yolu yenidən başlatmadan sonra hesabatları təhlil etməkdir.

Niyə ANR bəzi cihazlarda görünür, amma başqalarında yox?

Cihazın performansı, Android versiyası, CPU yükü və fon proseslərinin sayı ANR ehtimalına təsir edir. Zəif cihazlarda eyni əməliyyat 2–3 dəfə uzun çəkə bilər, 5 saniyəlik həddi keçərək.

BroadcastReceiver-in ANR-dən əvvəl vaxt limiti nə qədərdir?

Adi BroadcastReceiver üçün onReceive() daxilində 10 saniyə. Foreground xidmətlər üçün limit 20 saniyə, ContentProvider üçün isə açıq limit yoxdur, lakin əsas axının 5 saniyədən artıq bloklanması yenə də ANR-yə səbəb olur.

ANR nadir hallarda baş verirsə və təkrarlanmırsa nə etməli?

Bütün debug build-lərdə StrictMode-u aktivləşdirin, Firebase Crashlytics vasitəsilə monitorinq əlavə edin və ANR baş verdikdə adb bugreport istifadə edin. Qeyri-müntəzəm ANR-lər çox vaxt race condition və ya şəbəkənin spesifik vəziyyətləri ilə əlaqəlidir.

Nəticə

  • ANR — əsas axın 5 saniyədən artıq bloklandıqda işə düşən Android sistem mexanizmi
  • Əsas axın yalnız UI ilə məşğul olmalıdır — bütün digər əməliyyatlar fon axınlarına köçürülür
  • ANR diaqnozu traces.txt, Google Play Console və Firebase Crashlytics vasitəsilə aparılır
  • StrictMode real cihazda işə salmadan inkişaf mərhələsində potensial ANR-ləri aşkar edir
  • Coroutines Dispatchers.IO ilə — müasir Android layihələrində asinxron işin standart üsulu
  • BroadcastReceiver 10 saniyədən artıq iş üçün goAsync() və ya fon registratoru tələb edir
  • İstehsalatda ANR Crashlytics və Android 11 və yuxarıda daxili ApplicationExitInfo API vasitəsilə izlənir

Açar təslim mobil tətbiq hazırlayacağıq

IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.

Layihəni müzakirə et

Həm də oxuyun