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 (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.
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.
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.
fun fetchUserData() {
CoroutineScope(Dispatchers.Main).launch {
val result = withContext(Dispatchers.IO) {
api.getUserData() // fon əməliyyatı
}
updateUI(result) // əsas axında nəticə
}
}
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.
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 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.
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 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.
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 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 — 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.
if (BuildConfig.DEBUG) {
StrictMode.ThreadPolicy.Builder()
.detectDiskReads()
.detectDiskWrites()
.detectNetwork()
.penaltyLog()
.build()
.let { StrictMode.setThreadPolicy(it) }
}
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.
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.
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əyinat | Məlumat formatı |
|---|---|---|
| StrictMode | İnkişaf mərhələsində aşkarlama | Logcat / Exception |
| ANR Watchdog (Android Studio) | Real vaxtda izləmə | Thread dump + timeline |
| Google Play Console | Toplanmış statistika | ANR rate + stack traces |
| Firebase Crashlytics | İstehsalat monitorinqi | ApplicationExitInfo |
| adb bugreport | Tam 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 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 — 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.
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.
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.
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.
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ə
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.
Həm də oxuyun