ANR (Application Not Responding) — ito ay isang sistema ng abiso ng Android na lumalabas kapag ang application ay hindi tumugon sa input sa loob ng 5 segundo. Hindi tulad ng mga glitch (mga lohikal na error nang hindi hinaharangan ang UI) at lag (pagbagal nang walang kumpletong paghinto), ang ANR ay isang kritikal na pagkabigo na naitala ng operating system: Ipinapakita ng Android ang dialog na "Hindi Tumutugon ang Application" na may alok na isara o maghintay. Ayon sa Android Vitals Documentation, ang mga application na may ANR rate na higit sa 0.5% ay may mas mababang rating sa Google Play at maaaring itago mula sa mga rekomendasyon. Kasama sa diagnosis ang pagsusuri ng /data/anr/traces.txt, paggamit ng StrictMode at pag-profile sa pangunahing thread.
Mga Pangunahing Punto
ANR (Application Not Responding) — ito ay isang mekanismo ng proteksyon ng gumagamit sa Android na na-activate kapag huminto ang application sa pagtugon sa input. Sinusubaybayan ng system ang oras ng pagproseso ng mga kaganapan: kung ang BroadcastReceiver ay hindi makumpleto ang onReceive sa loob ng 10 segundo, ang Service ay hindi bumalik mula sa onCreate sa loob ng 20 segundo, at ang ContentProvider ay hindi tumugon sa loob ng 15 segundo — bubuo ang Android ng ANR.
Kapag naganap ang ANR, nagpapakita ang Android ng system dialog sa ibabaw ng lahat ng window: "Hindi Tumutugon ang Application. Isara o maghintay?". Maaaring isara ng gumagamit ang application o hintayin ang pagbawi nito. Kung madalas na umuulit ang ANR, tatanggalin ng gumagamit ang application. Isinasaalang-alang ng Google Play ang ANR rate — porsyento ng mga session na may ANR — sa mga algorithm ng pagraranggo.
Sa iOS, walang katumbas ng ANR na may system dialog. Sa halip, gumagamit ang Apple ng Watchdog na nagtatapos sa proseso ng application na may code na 0x8badf00d. Hindi nakikita ng gumagamit ang dialog — ang application ay basta na lang nagsasara sa pangunahing screen. Ginagawa nitong mas nakikita ang ANR sa Android para sa gumagamit, ngunit nagbibigay ito ng mas maraming impormasyon sa system para sa diagnosis.
Ang ANR ay nangyayari kapag sinusubaybayan ng system ang timeout para sa isa sa apat na uri ng mga component. Bawat component ay may sariling limitasyon sa oras.
BroadcastReceiver ay isinasagawa sa pangunahing thread. Kung ang onReceive ay maglunsad ng isang synchronous network request, mahabang operasyon ng pagsulat sa database, o maghintay para sa isang pagharang — pagkatapos ng 10 segundo ay lilitaw ang ANR. Solusyon: gumamit ng goAsync() at WorkManager para sa pagproseso sa background. Karaniwang senaryo — pagtanggap ng Push notification mula sa FCM at synchronous na pag-save sa Room.
Service.onCreate at Service.onStartCommand ay may limitasyon na 20 segundo. Kung ang serbisyo ay maglunsad ng mabigat na pagsisimula (pag-load ng mga library, pagbabasa ng configuration mula sa network) sa pangunahing thread — hindi maiiwasan ang ANR. Gumamit ng IntentService (luma na) o WorkManager para sa garantisadong pagpapatupad sa background thread.
ContentProvider.onCreate ay isinasagawa bago ang tawag sa Application.onCreate at may limitasyon na 15 segundo. Kung ang provider ay nagsasagawa ng database migration, pag-load ng mga diksyunaryo, o pagsisimula ng SDK mula sa network — ito ay nagdudulot ng ANR sa pagsisimula ng application. Solusyon: lazy-inisyalisasyon, paglipat ng mabibigat na operasyon sa WorkManager.
Ang Android ay nagbibigay ng ilang mga tool para sa pagsusuri ng ANR: mula sa system logs hanggang sa mga espesyalisadong library.
Sa bawat ANR, sine-save ng Android ang file na /data/anr/traces.txt na may dump ng mga stack ng lahat ng thread ng application. Hanapin ang thread na "main" — ang huling method sa stack ay nagpapahiwatig ng sanhi. Mga tipikal na pattern: Thread.sleep(), InputStream.read(), BinderProxy.transact(). Para kunin ang file mula sa device, gumamit ng adb na may mga karapatan ng superuser.
Firebase Crashlytics ay awtomatikong nangongolekta ng ANR at ipinapakita ang mga ito sa dashboard kasama ng pagsubaybay. Para sa Android 11+, ang mga ulat ng ANR ay dumarating na may kumpletong stack ng pangunahing thread. Ang pagsasama ay nangangailangan ng pagdaragdag ng dependency at pagsisimula ng FirebaseApp sa Application.onCreate.
CPU Profiler sa Android Studio ay nagpapahintulot sa iyo na mag-record ng pagsubaybay sa trabaho ng application at makita kung aling mga method ang kumukuha ng oras ng CPU. I-activate ang "Record with method traces" at i-reproduce ang senaryo na nagdudulot ng ANR. Sa timeline ay makikita kung aling mga method ang isinasagawa sa pangunahing thread sa sandali ng pag-freeze.
Halimbawa ng pagsasama ng Firebase Crashlytics para sa pagkolekta ng ANR sa Android:
class App : Application() {
override fun onCreate() {
super.onCreate()
FirebaseApp.initializeApp(this)
FirebaseCrashlytics.getInstance()
.setCrashlyticsCollectionEnabled(true)
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
.build())
}
}
Ang pag-aayos ng ANR ay pangunahing paglipat ng lahat ng mahabang operasyon mula sa pangunahing thread patungo sa mga background thread. Tingnan natin ang mga tiyak na teknik para sa bawat uri ng component.
WorkManager — ang inirerekomendang solusyon ng Google para sa trabaho sa background. Ginagarantiyahan nito ang pagpapatupad ng gawain sa background thread na isinasaalang-alang ang estado ng device. Hindi tulad ng Service, hindi hinaharangan ng WorkManager ang pangunahing thread at lumalaban sa pag-restart ng application. Para sa BroadcastReceiver, gumamit ng goAsync() at ipasa ang resulta na PendingResult sa WorkManager.
Lunsarin ang lahat ng network request, trabaho sa database, at file operations na may Dispatchers.IO. Ang pangunahing thread ay dapat lamang mag-update ng UI. Gumamit ng viewModelScope para sa awtomatikong pagkansela ng mga coroutine kapag nawasak ang Activity. Iwasan ang runBlocking() sa anumang konteksto — ito ay isang synchronous na pagharang sa kasalukuyang thread.
Kung ang ContentProvider ay nagsasagawa ng mahabang pagsisimula, gumamit ng mekanismo ng naantalang pag-load: lumikha ng provider na agad na nagbabalik ng data, at patakbuhin ang mabigat na pagsisimula sa pamamagitan ng WorkManager na may pagkaantala. Ito ay pumipigil sa ANR sa pagsisimula ng application, kapag ang sistema ay pinaka-sensitive sa mga pagkaantala.
Halimbawa ng tamang paggamit ng BroadcastReceiver na may goAsync sa Android:
class FcmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val pendingResult = goAsync()
WorkManager.getInstance(context!!)
.enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
pendingResult.finish()
}
}
Ang pinakamahusay na paraan upang labanan ang ANR ay pigilan ang kanilang paglitaw sa yugto ng pag-develop sa pamamagitan ng mga tool at solusyon sa arkitektura.
StrictMode na may mga naka-activate na patakaran na detectNetwork() at detectDiskReads()/detectDiskWrites() ay tumutuklas ng mga potensyal na ANR sa yugto ng pag-develop. Sa Debug build, itakda ang penaltyDeath — anumang paglabag ay hahantong sa agarang pag-crash, at makikita ng developer ang problema bago ang commit.
Firebase Performance ay sumusubaybay sa oras ng pagpapatupad ng mga pangunahing operasyon at nagpapakita kung aling mga senaryo ang lumalampas sa threshold ng ANR. I-configure ang mga custom na pagsubaybay para sa bawat screen at network request. Kung ang oras ng pagpapatupad ay lumampas sa 3 segundo — ito ay isang potensyal na ANR na nangangailangan ng optimisasyon.
Gayahin ang mabagal na kondisyon: limitahan ang bilis ng network sa pamamagitan ng Network Link Conditioner sa iOS o Android Emulator. Pabagalin ang pagbabasa mula sa disk sa pamamagitan ng emulasyon ng mabagal na memorya. ANR ay madalas na lilitaw sa mga ganitong kondisyon, sa mabilis na device ng developer ay hindi nakikita.
Mga Madalas Itanong
Android ay tahasang sumusubaybay sa oras ng pagproseso ng mga kaganapan sa pangunahing thread at nagpapakita ng ANR dialog. Ang iOS ay gumagamit ng Watchdog na pilit na nagsasara ng application kapag nag-freeze nang higit sa 10–20 segundo. Ang ANR ay isang tampok ng arkitektura ng Android kung saan ang ilang component (BroadcastReceiver, Service) ay may mahigpit na timeout.
Sa Android 11+ maaari kang makakuha ng ANR dump sa pamamagitan ng adb shell dumpsys dropbox --print data_app_anr. Sa Android 10 at mas mababa nang walang root ay walang access sa /data/anr/traces.txt. Gumamit ng Firebase Crashlytics — awtomatiko itong nangongolekta ng mga ulat ng ANR para sa Android 11+.
Inirerekomenda ng Google Play ang ANR rate na mas mababa sa 0.5% — ibig sabihin hindi hihigit sa 5 ANR bawat 1000 session. Ang application na may rate na higit sa 1% ay makakatanggap ng babala sa Google Play Console at maaaring itago mula sa mga rekomendasyon. Sa ideal, ang ANR rate ay dapat na mas mababa sa 0.1%.
Ang coroutine mismo ay hindi humaharang sa thread. Ngunit kung sa loob ng coroutine ay isinasagawa ang runBlocking sa pangunahing thread o ang coroutine ay inilunsad gamit ang Dispatchers.Main at nagsasagawa ng mahabang CPU operation — ito ay magdudulot ng ANR. Gumamit ng Dispatchers.IO para sa input-output at Dispatchers.Default para sa mga kalkulasyon.
Gumamit ng Android Emulator na may profile na "Slow Network" o sumulat ng test na tumatawag sa Thread.sleep(6000) sa pangunahing thread. Patakbuhin ang application sa pamamagitan ng Debug at pagkatapos ng 5 segundo makikita mo ang ANR dialog. Suriin kung sa logcat ay lumitaw ang isang tala ng ANR na may pagsubaybay.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din