ANR sa pag-develop ng Android — ano ito, mga sanhi at paraan ng pag-aayos

May-akda: IT Sectr Nai-publish: 2026-03-28 Oras ng pagbabasa: 9 min

ANR (Application Not Responding) — ito ay isang system notification ng Android na lumilitaw kapag ang app ay huminto sa pagtugon sa input ng user nang higit sa 5 segundo. Ayon sa Android Developers, ang pangunahing dahilan ay ang mahabang operasyon sa main thread na humaharang sa pagproseso ng mga pagpindot at pag-render ng interface. Ang pag-unawa sa mga mekanismo ng ANR ay kinakailangan para sa bawat Android developer upang lumikha ng mga responsive na application.

Mga pangunahing punto

  • ANR — babala ng system ng Android kapag nag-freeze ang app nang higit sa 5 segundo
  • Main thread (UI thread) — ang tanging lugar kung saan ang pag-block ay humahantong sa ANR
  • InputDispatcher — component ng system na nagtatala ng pagkaantala ng input at nagpasimula ng ANR
  • traces.txt — pangunahing file para sa pag-diagnose ng sanhi ng pag-freeze sa device
  • StrictMode — built-in na tool ng Android para sa pag-detect ng mahabang operasyon sa UI thread

Ano ang ANR

ANR (Application Not Responding) — ito ay isang dialog box ng operating system na Android na lumilitaw kapag ang app ay tumigil sa pagtugon sa input ng user. Sinusubaybayan ng system ang oras ng pagproseso ng mga event sa pamamagitan ng InputDispatcher: kung ang isang pagpindot o pagpindot ng button ay hindi naproseso sa loob ng 5 segundo, ang Android ay nagpapakita ng dialog na may alok na isara o hintayin ang app.

Pinoprotektahan ng mekanismo ng ANR ang karanasan ng gumagamit mula sa mga naka-freeze na app. Hindi pinapayagan ng Android ang isang app na harangan ang buong sistema — hindi tulad ng mga Desktop OS, ang mobile platform ay sapilitang naglilimita sa oras ng pagproseso ng event. Ang BroadcastReceiver ay may limitasyon na 10 segundo, at ang foreground service — 20 segundo.

Ang ANR ay HINDI exception sa code — ito ay isang sistema ng mekanismo sa antas ng mga proseso ng Linux. Nagpapadala ang Android ng SIGQUIT signal sa proseso, pagkatapos ay ini-save ng system ang stack ng tawag ng lahat ng thread sa file na traces.txt. Natatanggap ng developer ang ANR hindi bilang isang catch-exception, kundi bilang isang ulat pagkatapos ng restart ng app. Sa Android 11+ lumitaw ang API na ApplicationExitInfo na nagpapahintulot na makuha ang dahilan ng pagtatapos ng proseso nang programmatically, kabilang ang ANR — pinapasimple nito ang pagkolekta ng statistics nang walang manu-manong pag-parse ng traces.txt.

Mga pangunahing sanhi ng ANR

Limang kategorya ng operasyon ang patuloy na humahantong sa ANR sa mga Android app. Bawat isa ay humaharang sa main thread, na pumipigil sa system na magproseso ng input events at mag-redraw ng screen.

Mga network request sa main thread

Mga synchronous HTTP request na isinagawa sa UI thread — ang pinakakaraniwang sanhi ng ANR sa mga baguhang developer. Kahit ang mabilis na request sa server ay maaaring tumagal ng 1–3 segundo, at sa mahinang koneksyon — 30 segundo o higit pa. Hayagang ipinagbabawal ng Android ang network operations sa main thread simula sa API 11, na nagtatapon ng NetworkOnMainThreadException.

Gamitin ang Coroutines o RxJava para sa asynchronous na mga tawag. Ang mga coroutine na may dispatcher na Dispatchers.IO ay nag-execute ng request sa background thread, at ang resulta ay ipinapadala sa main thread sa pamamagitan ng Dispatchers.Main. Ito ay ganap na nag-aalis ng pag-block ng UI thread ng network operations.

kotlin
fun fetchUserData() {
    CoroutineScope(Dispatchers.Main).launch {
        val result = withContext(Dispatchers.IO) {
            api.getUserData() // background operation
        }
        updateUI(result) // resulta sa main thread
    }
}

Intensive computations sa UI thread

Pagproseso ng malalaking array ng data, pag-parse ng JSON o XML, direktang trabaho sa bitmap sa main thread — pangalawang pinakakaraniwang sanhi ng ANR. Kahit 300 milliseconds ng tuluy-tuloy na trabaho ng UI thread nang hindi bumabalik sa event loop ay nagdudulot ng kapansin-pansing pagkaantala sa rendering, at ang limit na 5 segundo ay naitala bilang ANR.

WorkManager at background services ay dinisenyo upang ilipat ang mabibigat na computations mula sa main thread. Gamitin ang AsyncTask (luma na), ListenableFuture o Kotlin Flow upang magpadala ng data sa mga bahagi, nang hindi hina-block ang UI.

Mga lock sa synchronization at Deadlock

Deadlock ay nangyayari kapag dalawang thread ay humahawak ng mga lock at naghihintay sa isa't isa. Kung ang isa sa mga thread ay ang main, ang system ay nagtatala ng ANR eksaktong pagkatapos ng 5 segundo. Ang Thread.join(), CountDownLatch.await() at synchronized blocks na tinawag mula sa UI thread ay nagdadala ng panganib ng pag-block.

Iwasan ang lahat ng blocking operations sa main thread. Sa halip na synchronized gamitin ang ConcurrentHashMap, sa halip na Thread.join() — coroutines na may async/await. Ang patakarang ito ay nalalapat sa bawat wika sa Android: Java, Kotlin o C++ sa pamamagitan ng JNI.

Mahabang trabaho ng BroadcastReceiver

BroadcastReceiver ay bilang default ay tumatakbo sa main thread. Kung ang onReceive() ay abala nang higit sa 10 segundo, ang Android ay nagpapakita ng ANR. Ang pag-load ng data mula sa database o network sa loob ng onReceive ay isang garantisadong daan patungo sa pag-freeze.

Gamitin ang goAsync() sa loob ng BroadcastReceiver upang lumipat sa background thread, o registerReceiver na may getBackgroundBroadcastReceiver(). Ito ay nagpapahintulot ng pagproseso ng mga event nang hindi hinaharangan ang UI.

ContentProvider at SQLite sa main thread

Mabibigat na query sa ContentProvider o direktang trabaho sa SQLite sa UI thread — hindi gaanong halata ngunit karaniwang sanhi ng ANR. Sa panahon ng database migration o bulk insertion ng libu-libong record, ang oras ng pag-execute ay maaaring lumampas sa limit na 5 segundo.

Ilipat ang lahat ng database operations sa background threads sa pamamagitan ng Room na may suspend functions. Awtomatikong sinusuri ng Room na ang query ay hindi isinasagawa sa main thread at nagtatapon ng exception kung nilabag.

Paano i-diagnose ang ANR

Ang pag-diagnose ng ANR ay naiiba sa pag-debug ng ordinaryong exceptions — hindi mo mahuhuli ang ANR sa try-catch. Ang pangunahing source ng impormasyon ay ang file na traces.txt na nilikha ng Android sa sandali ng pag-freeze.

traces.txt ay naglalaman ng stack ng tawag ng lahat ng thread ng app sa sandali ng ANR. Upang basahin ang file mula sa isang tunay na device, isagawa ang command na adb bugreport na nangongolekta ng kumpletong ulat ng system, kabilang ang lahat ng ANR sa nakaraang panahon. Para sa emulator, ang file ay available sa /data/anr/traces.txt. Ang stack ng tawag ay nagpapakita kung aling method ang isinasagawa sa main thread sa sandali ng pag-block.

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

Google Play Console ay nagbibigay ng seksyong ANR & Crash na may aggregated reports at frequency ng error. Para sa bawat ANR ay ipinapakita ang stack ng tawag at statistics ayon sa device: modelo, bersyon ng Android, rehiyon. Ito ay nagpapahintulot ng pagtukoy ng ANR na nakadepende sa mga partikular na device o bersyon ng system.

Ang Android Studio mula 2021 ay naglalaman ng ANR Watchdog sa profiler. Awtomatiko itong nagre-record ng dump ng threads kung ang main thread ay hindi tumugon nang mas matagal sa threshold time. Ipinapakita ng tool ang timeline ng mga event: kung anong operations ang inilunsad, kung anong methods ang isinagawa at sa anong yugto naganap ang pag-block.

Paano maiwasan ang ANR

Ang pag-iwas sa ANR ay nakabatay sa isang pangunahing patakaran: ang main thread ay dapat lamang magproseso ng UI events. Anumang operasyon na tumatagal nang higit sa 16 milliseconds (oras ng isang frame) ay dapat isagawa sa background thread.

StrictMode — awtomatikong pagsusuri

StrictMode — built-in na tool ng Android para sa pag-detect ng mga potensyal na ANR sa yugto ng pag-develop. I-activate ito sa Application.onCreate() na may mga flag para sa disk at network operations. Sa paglabag, ang StrictMode ay nagtatapon ng exception o nagsusulat sa logcat.

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

Asynchronous patterns: Coroutines at RxJava

Kotlin Coroutines — ang karaniwang paraan ng asynchronous na trabaho sa modernong Android apps. Pangunahing prinsipyo: ang input-output operations ay isinasagawa sa Dispatchers.IO, ang resulta ay ipinapadala sa Dispatchers.Main para sa UI update. Para sa Flow scenarios, gamitin ang Dispatchers.Default para sa CPU-intensive tasks.

RxJava ay nananatiling popular sa legacy projects. subscribeOn(Schedulers.io()) at observeOn(AndroidSchedulers.mainThread()) — minimal na set para sa pag-iwas sa ANR. Parehong patakaran: walang Observable o Flowable ang dapat mag-emit ng data mula sa main thread.

Monitoring sa produksyon

Firebase Crashlytics mula sa bersyon SDK 18.4.0 ay sumusuporta sa ANR monitoring out of the box. Para sa Android 11+ ginagamit ng Crashlytics ang system API na ApplicationExitInfo na nagbibigay ng eksaktong dahilan ng pagtatapos: ANR, Crash o pagpatay ng system. I-activate ang custom keys na may screen at state parameters para sa contextual analysis.

Mga tool para sa pag-detect ng ANR

Limang tool ay sumasaklaw sa lahat ng yugto ng trabaho sa ANR: mula sa pag-debug sa workstation hanggang sa monitoring sa produksyon. Bawat tool ay lumulutas ng sarili nitong gawain at nagbibigay ng data para sa iba't ibang scenarios.

ToolLayuninFormat ng data
StrictModePagtukoy sa yugto ng pag-developLogcat / Exception
ANR Watchdog (Android Studio)Real-time na pagsubaybayThread dump + timeline
Google Play ConsoleAgregadong statisticsANR rate + stack traces
Firebase CrashlyticsMonitoring sa produksyonApplicationExitInfo
adb bugreportKumpletong ulat ng systemtraces.txt + logcat + dmesg

Bawat tool ay may sariling angkop na lugar: StrictMode ay humuhuli ng halatang paglabag sa maagang yugto, Crashlytics ay nagpapakita ng tunay na frequency ng ANR sa mga user, at adb bugreport ay nagbibigay ng pinakakumpletong larawan para sa mga kumplikadong kaso. Pagsamahin ang mga ito para sa buong coverage.

Firebase Performance Monitoring

Firebase Performance ay sumusubaybay sa oras ng pagtugon ng UI thread at awtomatikong gumagawa ng mga trace para sa kahina-hinalang mahahabang operasyon. Kung ang main thread ay naharang nang higit sa 500 ms, ang Performance ay nagtatala ng custom trace na may pangalan ng method na may sala. Ito ay nagpapahintulot ng pag-detect ng ANR scenarios nang walang partisipasyon ng user at bago sila maging kritikal.

Ang pagsasama sa Firebase Crashlytics ay nagbibigay ng kumpletong larawan: Performance ay nagpapakita ng mga pagbagal bago ang ANR, at Crashlytics — ang mismong katotohanan ng pag-freeze. I-configure ang mga alerto sa Firebase Console para sa event na ANR rate na higit sa 0.1% at makakatanggap ka ng mga notification tungkol sa mga bagong problema bago ang mga mass complaint ng user.

Mga madalas itanong

Paano naiiba ang ANR sa Crash?

ANR — ay isang pag-freeze kung saan ang app ay hindi tumutugon ngunit nananatili sa memorya. Crash — kumpletong emergency termination na may exit mula sa proseso. Ang ANR ay maaaring makaligtas kung ang system o user ay maghintay ng sagot, habang ang Crash ay palaging nagtatapos sa app.

Maaari bang mahuli ang ANR sa pamamagitan ng try-catch?

Hindi. Ang ANR ay hindi Java/Kotlin exception, kundi isang system signal sa antas ng proseso (SIGQUIT). Hindi ito maproseso ng developer sa code ng app. Ang tanging paraan upang tumugon sa ANR ay ang pag-analyze ng mga ulat pagkatapos ng restart.

Bakit lumilitaw ang ANR sa ilang device ngunit hindi sa iba?

Performance ng device, bersyon ng Android, load ng CPU at bilang ng background processes ay nakakaapekto sa posibilidad ng ANR. Sa mahihinang device, ang parehong operasyon ay maaaring tumagal ng 2–3 beses na mas matagal, lumalampas sa limit na 5 segundo.

Ano ang limitasyon ng oras ng BroadcastReceiver bago ang ANR?

10 segundo para sa ordinaryong BroadcastReceiver sa onReceive(). Para sa foreground services ang limit ay 20 segundo, at para sa ContentProvider ay walang malinaw na limit, ngunit ang pag-block ng main thread nang higit sa 5 segundo ay nagdudulot pa rin ng ANR.

Ano ang gagawin kung ang ANR ay bihirang mangyari at hindi ma-reproduce?

I-activate ang StrictMode sa lahat ng debug builds, magdagdag ng monitoring sa pamamagitan ng Firebase Crashlytics at gamitin ang adb bugreport kapag nangyari ang ANR. Ang mga hindi regular na ANR ay madalas na nauugnay sa race condition o mga partikular na kondisyon ng network.

Buod

  • ANR — mekanismo ng system ng Android na naa-activate kapag ang main thread ay naharang nang higit sa 5 segundo
  • Main thread ay dapat lamang humawak ng UI — lahat ng iba pang operasyon ay inililipat sa background threads
  • Diagnosis ng ANR ay ginagawa sa pamamagitan ng traces.txt, Google Play Console at Firebase Crashlytics
  • StrictMode ay tumutukoy ng potensyal na ANR sa yugto ng pag-develop nang hindi tumatakbo sa isang tunay na device
  • Coroutines na may Dispatchers.IO — karaniwang paraan ng asynchronous na trabaho sa modernong Android projects
  • BroadcastReceiver ay nangangailangan ng goAsync() o background registrar para sa trabaho nang higit sa 10 segundo
  • ANR sa produksyon ay mino-monitor sa pamamagitan ng Crashlytics at built-in na API ApplicationExitInfo sa Android 11 pataas

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.

Pag-usapan ang proyekto

Basahin din