← Назад к вопросам

Что такое ANR (Application Not Responding)?

1.0 Junior🔥 261 комментариев
#Производительность и оптимизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое ANR (Application Not Responding)?

ANR (Application Not Responding, «Приложение не отвечает») — это критическое состояние в Android-приложении, когда основной поток (UI Thread или Main Thread) блокируется дольше допустимого времени, что приводит к «зависанию» интерфейса. Система Android обнаруживает это и показывает пользователю диалоговое окно с предложением закрыть приложение, чтобы сохранить отзывчивость системы. Это серьёзная ошибка, напрямую влияющая на пользовательский опыт.

Причины возникновения ANR

ANR возникает, когда основной поток занят длительной операцией и не может обрабатывать ввод пользователя или обновлять UI. Система Android устанавливает жёсткие временные лимиты:

  1. Ввод/событие (например, касание или нажатие клавиши): 5 секунд. Если основной поток не обработал событие ввода за это время.
  2. BroadcastReceiver: 10 секунд для выполнения метода onReceive().
  3. Сервис (Service): 20 секунд для запуска сервиса через startService() (для foreground-сервиса лимит больше).

Если лимит превышен, система выводит диалог ANR и создаёт traces-файл (/data/anr/traces.txt), который помогает в диагностике.

Типичные сценарии, приводящие к ANR

  • Долгие операции в UI-потоке: Сетевые запросы, сложные вычисления, чтение/запись больших файлов, запросы к базе данных.
  • Взаимные блокировки (deadlocks): Основной поток ожидает ресурс, который удерживается другим потоком, в то время как сам этот поток ожидает что-то от основного.
  • Блокировки на основной поток из фонового: Например, вызов runOnUiThread() или обращение к View из фонового потока, в то время как основной поток заблокирован.
  • Чрезмерная нагрузка на основной поток: Обработка огромного количества сообщений в Handler или Looper.

Как диагностировать ANR

Ключевой инструмент — анализ traces-файла, который система сохраняет при возникновении ANR. В нём содержится «снимок» состояния всех потоков приложения в момент ошибки.

Пример ANR в логах:

ANR in com.example.myapp (com.example.myapp/.MainActivity)
...
----- pid 12345 at 2023-11-01 12:00:00 -----
Cmd line: com.example.myapp
...
"main" prio=5 tid=1 Runnable
  | group="main" sCount=0 dsCount=0 flags=0 obj=0x12c00000 self=0x7f8e0a4000
  | sysTid=12345 nice=-10 cgrp=default sched=0/0 handle=0x7fa1a4a4f0
  | state=R schedstat=( ... ) utm=10 stm=5 core=1 HZ=100
  | stack=0x7fc34a8000-0x7fc34aa000
  | held mutexes= "mutator lock"(shared held)
  at com.example.myapp.MainActivity.heavyCalculation(MainActivity.java:42)
  at com.example.myapp.MainActivity.onCreate(MainActivity.java:31)
...

Анализ: В стек-трейсе видно, что в момент ANR основной поток ("main") выполнял метод heavyCalculation(), который и привёл к блокировке.

Как предотвращать ANR: лучшие практики

  1. Не блокируйте основной поток. Все длительные операции (IO, сеть, вычисления) должны выполняться в фоновых потоках или корутинах.

    // НЕПРАВИЛЬНО - вызов сети в UI-потоке
    fun loadData() {
        val response = networkApi.getData().execute() // Блокирующий вызов!
        updateUI(response)
    }
    
    // ПРАВИЛЬНО - использование корутин
    fun loadData() {
        viewModelScope.launch {
            val response = withContext(Dispatchers.IO) {
                networkApi.getData() // Неблокирующий suspend-вызов
            }
            updateUI(response) // Возвращаемся в Main
        }
    }
    
  2. Используйте современные инструменты многопоточности: Kotlin Coroutines с Dispatchers.Main/IO/Default или LiveData/Flow для наблюдения за данными.

  3. Оптимизируйте выполнение в основном потоке:

    *   Избегайте создания сложных View-иерархий.
    *   Используйте `RecyclerView` вместо `ListView`.
    *   Оптимизируйте layout-файлы, избегайте глубокой вложенности.
  1. Для BroadcastReceiver: выполняйте минимальную работу в onReceive() и запускайте IntentService или WorkManager для длительных задач.
  2. Используйте StrictMode для обнаружения потенциальных проблем на этапе разработки.
  3. Мониторинг производительности: Используйте Android Vitals в Google Play Console или библиотеки типа Firebase Performance Monitoring для отслеживания ANR в продакшене.

Заключение

ANR — это не просто ошибка, а прямое нарушение принципа отзывчивости приложения. Для Android-разработчика понимание природы ANR, умение анализировать traces и следование принципам реактивного программирования являются обязательными навыками. Современные архитектурные подходы (MVVM, MVI) и асинхронные инструменты (Kotlin Coroutines, RxJava) существенно снижают риски возникновения ANR, перенося всю работу с данными в фоновые потоки и оставляя основной поток свободным для рендеринга UI и обработки пользовательского ввода.

Что такое ANR (Application Not Responding)? | PrepBro