ANR στο Android: τι είναι, αιτίες και μέθοδοι αντιμετώπισης

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-07-28 Χρόνος ανάγνωσης: 9 λεπ

ANR (Application Not Responding) — είναι μια ειδοποίηση συστήματος Android που εμφανίζεται όταν η εφαρμογή δεν ανταποκρίνεται στην είσοδο για 5 δευτερόλεπτα. Σε αντίθεση με τα glitch (λογικά σφάλματα χωρίς μπλοκάρισμα του UI) και τα lag (επιβράδυνση χωρίς πλήρη διακοπή), το ANR είναι μια κρίσιμη βλάβη που καταγράφεται από το λειτουργικό σύστημα: το Android εμφανίζει το παράθυρο διαλόγου «Η εφαρμογή δεν αποκρίνεται» με πρόταση να κλείσει ή να περιμένετε. Σύμφωνα με το Android Vitals Documentation, οι εφαρμογές με ποσοστό ANR άνω του 0,5% έχουν χαμηλότερη βαθμολογία στο Google Play και ενδέχεται να κρυφτούν από τις προτάσεις. Η διάγνωση περιλαμβάνει ανάλυση του /data/anr/traces.txt, χρήση του StrictMode και προφίλ του κύριου νήματος.

Κύρια σημεία

  • ANR — ειδοποίηση συστήματος Android όταν το κύριο νήμα μπλοκάρεται για περισσότερο από 5 δευτερόλεπτα, οδηγώντας στο παράθυρο διαλόγου «Η εφαρμογή δεν αποκρίνεται»
  • Κύριες αιτίες — μπλοκάρισμα του κύριου νήματος (BroadcastReceiver, Service), deadlock μεταξύ νημάτων, μεγάλη λειτουργία στο ContentProvider
  • Διάγνωση — ανάλυση /data/anr/traces.txt, Android Studio Profiler, Firebase Performance Monitoring
  • Διόρθωση — μεταφορά εργασιών στο WorkManager, χρήση Kotlin Coroutines με Dispatchers.IO, StrictMode για έγκαιρη ανίχνευση
  • Πρόληψη — περιορισμός χρόνου BroadcastReceiver σε 10 δευτερόλεπτα, Service σε 20 δευτερόλεπτα, ContentProvider σε 15 δευτερόλεπτα

Τι είναι το ANR στο Android

ANR (Application Not Responding) — είναι ένας μηχανισμός προστασίας του χρήστη στο Android που ενεργοποιείται όταν η εφαρμογή σταματά να ανταποκρίνεται στην είσοδο. Το σύστημα παρακολουθεί τον χρόνο επεξεργασίας συμβάντων: εάν το BroadcastReceiver δεν ολοκληρώσει το onReceive εντός 10 δευτερολέπτων, το Service δεν επιστρέψει από το onCreate εντός 20 δευτερολέπτων και το ContentProvider δεν απαντήσει εντός 15 δευτερολέπτων — το Android δημιουργεί ANR.

Πώς εμφανίζεται το ANR στον χρήστη

Όταν συμβαίνει ANR, το Android εμφανίζει ένα παράθυρο διαλόγου συστήματος πάνω από όλα τα παράθυρα: «Η εφαρμογή δεν αποκρίνεται. Να κλείσει ή να περιμένετε;». Ο χρήστης μπορεί να κλείσει την εφαρμογή ή να περιμένει την ανάκτησή της. Εάν τα ANR επαναλαμβάνονται συχνά, ο χρήστης διαγράφει την εφαρμογή. Το Google Play λαμβάνει υπόψη το ποσοστό ANR — το ποσοστό συνεδριών με ANR — στους αλγόριθμους κατάταξης.

Διαφορά μεταξύ ANR και παγώματος στο iOS

Στο iOS δεν υπάρχει αντίστοιχο του ANR με παράθυρο διαλόγου συστήματος. Αντίθετα, η Apple χρησιμοποιεί το Watchdog, το οποίο τερματίζει τη διαδικασία της εφαρμογής με κωδικό 0x8badf00d. Ο χρήστης δεν βλέπει παράθυρο διαλόγου — η εφαρμογή απλά κλείνει στην αρχική οθόνη. Αυτό καθιστά το ANR στο Android πιο ορατό στον χρήστη, αλλά δίνει στο σύστημα περισσότερες πληροφορίες για διάγνωση.

Κύριες αιτίες του ANR

Το ANR συμβαίνει όταν το σύστημα παρακολουθεί χρονικό όριο για έναν από τους τέσσερις τύπους στοιχείων. Κάθε στοιχείο έχει το δικό του χρονικό όριο.

Μπλοκάρισμα στο BroadcastReceiver

BroadcastReceiver εκτελείται στο κύριο νήμα. Εάν το onReceive ξεκινήσει ένα σύγχρονο αίτημα δικτύου, μια μεγάλη λειτουργία εγγραφής στη βάση δεδομένων ή αναμονή για μπλοκάρισμα — μετά από 10 δευτερόλεπτα εμφανίζεται ANR. Λύση: χρησιμοποιήστε goAsync() και WorkManager για επεξεργασία στο παρασκήνιο. Τυπικό σενάριο — λήψη ειδοποίησης Push από το FCM και σύγχρονη αποθήκευση στο Room.

Μεγάλη λειτουργία στο Service

Service.onCreate και Service.onStartCommand έχουν όριο 20 δευτερολέπτων. Εάν η υπηρεσία ξεκινήσει βαριά αρχικοποίηση (φόρτωση βιβλιοθηκών, ανάγνωση παραμέτρων από το δίκτυο) στο κύριο νήμα — το ANR είναι αναπόφευκτο. Χρησιμοποιήστε IntentService (ξεπερασμένο) ή WorkManager για εγγυημένη εκτέλεση στο νήμα παρασκηνίου.

ContentProvider με μεγάλη αρχικοποίηση

ContentProvider.onCreate εκτελείται πριν από την κλήση του Application.onCreate και έχει όριο 15 δευτερολέπτων. Εάν ο πάροχος εκτελεί μετεγκατάσταση βάσης δεδομένων, φόρτωση λεξικών ή αρχικοποίηση SDK από το δίκτυο — αυτό προκαλεί ANR κατά την εκκίνηση της εφαρμογής. Λύση: τεμπέλικη αρχικοποίηση, μεταφορά βαριών λειτουργιών στο WorkManager.

  • BroadcastReceiver — 10 δευτερόλεπτα για onReceive; χρησιμοποιήστε goAsync() για επεξεργασία παρασκηνίου
  • Service — 20 δευτερόλεπτα για onCreate/onStartCommand; χρησιμοποιήστε WorkManager ή CoroutineWorker
  • ContentProvider — 15 δευτερόλεπτα για onCreate; μεταφέρετε την αρχικοποίηση στο Application.onCreate με καθυστερημένη εκκίνηση
  • Νήμα UI — 5 δευτερόλεπτα χωρίς επεξεργασία συμβάντων; οποιοδήποτε μπλοκάρισμα μεγαλύτερο από 5 δευτερόλεπτα προκαλεί ANR

Πώς να διαγνώσετε το ANR

Το Android παρέχει διάφορα εργαλεία για ανάλυση ANR: από αρχεία καταγραφής συστήματος έως εξειδικευμένες βιβλιοθήκες.

Ανάλυση traces.txt

Σε κάθε ANR, το Android αποθηκεύει το αρχείο /data/anr/traces.txt με απόρριψη στοίβας όλων των νημάτων της εφαρμογής. Βρείτε το νήμα «main» — η τελευταία μέθοδος στη στοίβα υποδεικνύει την αιτία. Τυπικά μοτίβα: Thread.sleep(), InputStream.read(), BinderProxy.transact(). Για εξαγωγή του αρχείου από τη συσκευή, χρησιμοποιήστε adb με δικαιώματα υπερχρήστη.

Firebase Crashlytics με αναφορές ANR

Firebase Crashlytics συλλέγει αυτόματα ANR και τα εμφανίζει στον πίνακα ελέγχου μαζί με ιχνηλάτηση. Για Android 11+, οι αναφορές ANR έρχονται με πλήρη στοίβα του κύριου νήματος. Η ενοποίηση απαιτεί προσθήκη εξάρτησης και αρχικοποίηση του FirebaseApp στο Application.onCreate.

Android Studio Profiler με ιχνηλάτηση νημάτων

CPU Profiler στο Android Studio σας επιτρέπει να καταγράψετε ιχνηλάτηση της λειτουργίας της εφαρμογής και να δείτε ποιες μέθοδοι καταλαμβάνουν χρόνο CPU. Ενεργοποιήστε το «Record with method traces» και αναπαράγετε το σενάριο που προκαλεί ANR. Στη γραμμή χρόνου θα είναι ορατό ποιες μέθοδοι εκτελούνταν στο κύριο νήμα τη στιγμή του παγώματος.

Παράδειγμα ενοποίησης Firebase Crashlytics για συλλογή ANR στο Android:

kotlin
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        FirebaseApp.initializeApp(this)
        FirebaseCrashlytics.getInstance()
            .setCrashlyticsCollectionEnabled(true)
        StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .build())
    }
}

Μέθοδοι αντιμετώπισης του ANR

Η αντιμετώπιση του ANR σημαίνει πρωτίστως μεταφορά όλων των μεγάλων λειτουργιών από το κύριο νήμα στα νήματα παρασκηνίου. Ας εξετάσουμε συγκεκριμένες τεχνικές για κάθε τύπο στοιχείου.

Χρήση WorkManager για εργασίες παρασκηνίου

WorkManager — η συνιστώμενη λύση της Google για εργασία στο παρασκήνιο. Εγγυάται την εκτέλεση της εργασίας στο νήμα παρασκηνίου λαμβάνοντας υπόψη την κατάσταση της συσκευής. Σε αντίθεση με το Service, το WorkManager δεν μπλοκάρει το κύριο νήμα και είναι ανθεκτικό στην επανεκκίνηση της εφαρμογής. Για BroadcastReceiver, χρησιμοποιήστε goAsync() και μεταβιβάστε το αποτέλεσμα PendingResult στο WorkManager.

Kotlin Coroutines με σωστούς διανομείς

Εκκινήστε όλα τα αιτήματα δικτύου, την εργασία με βάση δεδομένων και τις λειτουργίες αρχείων με Dispatchers.IO. Το κύριο νήμα πρέπει μόνο να ενημερώνει το UI. Χρησιμοποιήστε viewModelScope για αυτόματη ακύρωση coroutine κατά την καταστροφή του Activity. Αποφύγετε το runBlocking() σε οποιοδήποτε περιβάλλον — αυτό είναι σύγχρονο μπλοκάρισμα του τρέχοντος νήματος.

Τεμπέλικη αρχικοποίηση ContentProvider

Εάν το ContentProvider εκτελεί μεγάλη αρχικοποίηση, χρησιμοποιήστε μηχανισμό καθυστερημένης φόρτωσης: δημιουργήστε έναν πάροχο που επιστρέφει άμεσα δεδομένα και εκκινήστε τη βαριά αρχικοποίηση μέσω WorkManager με καθυστέρηση. Αυτό αποτρέπει το ANR κατά την εκκίνηση της εφαρμογής, όταν το σύστημα είναι πιο ευαίσθητο σε καθυστερήσεις.

Παράδειγμα σωστής χρήσης BroadcastReceiver με goAsync στο Android:

kotlin
class FcmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        val pendingResult = goAsync()
        WorkManager.getInstance(context!!)
            .enqueue(OneTimeWorkRequest.from(NotificationWorker::class.java))
        pendingResult.finish()
    }
}

Πρόληψη του ANR στην ανάπτυξη

Ο καλύτερος τρόπος αντιμετώπισης του ANR είναι η πρόληψη της εμφάνισής τους στο στάδιο ανάπτυξης μέσω εργαλείων και αρχιτεκτονικών λύσεων.

StrictMode για ανίχνευση μπλοκαρίσματος του κύριου νήματος

StrictMode με ενεργοποιημένες πολιτικές detectNetwork() και detectDiskReads()/detectDiskWrites() ανιχνεύει πιθανά ANR στο στάδιο ανάπτυξης. Στην έκδοση Debug, ορίστε penaltyDeath — οποιαδήποτε παραβίαση θα οδηγήσει σε άμεση κατάρρευση και ο προγραμματιστής θα δει το πρόβλημα πριν από την υποβολή.

Firebase Performance Monitoring για μετρήσεις παραγωγής

Firebase Performance παρακολουθεί τον χρόνο εκτέλεσης βασικών λειτουργιών και δείχνει ποια σενάρια υπερβαίνουν το όριο ANR. Διαμορφώστε προσαρμοσμένες ιχνηλατήσεις για κάθε οθόνη και αίτημα δικτύου. Εάν ο χρόνος εκτέλεσης υπερβαίνει τα 3 δευτερόλεπτα — αυτό είναι ένα πιθανό ANR που απαιτεί βελτιστοποίηση.

Δοκιμές με καθυστερήσεις δικτύου και δίσκου

Προσομοιώστε αργές συνθήκες: περιορίστε την ταχύτητα δικτύου μέσω του Network Link Conditioner στο iOS ή στο Android Emulator. Επιβραδύνετε την ανάγνωση από τον δίσκο μέσω εξομοίωσης αργής μνήμης. ANR εμφανίζεται συχνά ακριβώς σε τέτοιες συνθήκες, στις γρήγορες συσκευές του προγραμματιστή δεν είναι ορατό.

  • BroadcastReceiver — χρησιμοποιείτε πάντα goAsync() για επεξεργασία μεγαλύτερη από 1 δευτερόλεπτο
  • Service — αντικαταστήστε με WorkManager ή CoroutineWorker με διανομέα παρασκηνίου
  • ContentProvider — αποφύγετε δίκτυο και βάση δεδομένων στο onCreate, χρησιμοποιήστε lazy-init με WorkManager
  • Νήμα UI — StrictMode με penaltyDeath στο Debug, Firebase Performance για παρακολούθηση παραγωγής

Συχνές Ερωτήσεις

Γιατί εμφανίζεται ANR στο Android αλλά όχι στο iOS;

Android παρακολουθεί ρητά τον χρόνο επεξεργασίας συμβάντων στο κύριο νήμα και εμφανίζει το παράθυρο διαλόγου ANR. Το iOS χρησιμοποιεί Watchdog, το οποίο κλείνει αναγκαστικά την εφαρμογή όταν παγώνει για περισσότερο από 10–20 δευτερόλεπτα. Το ANR είναι χαρακτηριστικό της αρχιτεκτονικής Android, όπου πολλά στοιχεία (BroadcastReceiver, Service) έχουν αυστηρά χρονικά όρια.

Πώς να βρω το traces.txt σε συσκευή χωρίς root;

Σε Android 11+ μπορείτε να λάβετε απόρριψη ANR μέσω adb shell dumpsys dropbox --print data_app_anr. Σε Android 10 και παλαιότερα χωρίς root δεν υπάρχει πρόσβαση στο /data/anr/traces.txt. Χρησιμοποιήστε Firebase Crashlytics — συλλέγει αυτόματα αναφορές ANR για Android 11+.

Ποιο ποσοστό ANR θεωρείται αποδεκτό;

Το Google Play συνιστά ποσοστό ANR κάτω από 0,5% — δηλαδή όχι περισσότερα από 5 ANR ανά 1000 συνεδρίες. Η εφαρμογή με ποσοστό άνω του 1% λαμβάνει προειδοποίηση στο Google Play Console και μπορεί να κρυφτεί από τις προτάσεις. Ιδανικά, το ποσοστό ANR θα πρέπει να είναι κάτω από 0,1%.

Μπορεί ένα coroutine να προκαλέσει ANR;

Το coroutine από μόνο του δεν μπλοκάρει το νήμα. Αλλά εάν μέσα στο coroutine εκτελείται runBlocking στο κύριο νήμα ή το coroutine εκκινείται με Dispatchers.Main και εκτελεί μεγάλη λειτουργία CPU — αυτό θα προκαλέσει ANR. Χρησιμοποιήστε Dispatchers.IO για είσοδο-έξοδο και Dispatchers.Default για υπολογισμούς.

Πώς να δοκιμάσω το ANR σε εξομοιωτή;

Χρησιμοποιήστε Android Emulator με προφίλ «Slow Network» ή γράψτε μια δοκιμή που καλεί Thread.sleep(6000) στο κύριο νήμα. Εκκινήστε την εφαρμογή μέσω Debug και μετά από 5 δευτερόλεπτα θα δείτε το παράθυρο διαλόγου ANR. Ελέγξτε ότι στο logcat εμφανίστηκε μια εγγραφή ANR με ιχνηλάτηση.

Σύνοψη

  • ANR — ειδοποίηση συστήματος Android όταν το κύριο νήμα μπλοκάρεται για περισσότερο από 5 δευτερόλεπτα ή όταν ξεπερνιούνται τα χρονικά όρια στοιχείων
  • Χρονικά όρια: BroadcastReceiver — 10 δ, Service — 20 δ, ContentProvider — 15 δ, UI — 5 δ
  • Διάγνωση — /data/anr/traces.txt, Firebase Crashlytics, CPU Profiler στο Android Studio
  • Διόρθωση — WorkManager, goAsync(), Kotlin Coroutines με Dispatchers.IO, τεμπέλικη αρχικοποίηση ContentProvider
  • Πρόληψη — StrictMode με penaltyDeath, Firebase Performance Monitoring, δοκιμές με καθυστερήσεις δικτύου
  • Google Play συνιστά ποσοστό ANR < 0,5%; σε ποσοστό > 1% η εφαρμογή υπόκειται σε περιορισμούς ορατότητας
  • Σύσταση: διαμορφώστε Firebase Crashlytics και Performance για συλλογή ANR στην παραγωγή και ορίστε ειδοποιήσεις όταν ξεπερνιέται το όριο του 0,3%

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης