Что означает ошибка ANR
ANR (Application Not Responding) — это системное диалоговое окно Android, которое появляется, когда главный поток приложения не отвечает более 5 секунд. Пользователь видит три кнопки: «Подождать», «Закрыть» и «Отправить отчет». Если выбрать «Подождать», система дает приложению еще время на реакцию, но в большинстве случаев приложение все равно закрывается.
Ошибка ANR блокирует любое взаимодействие с приложением: нажатия, скроллинг, ввод текста. Она обычно возникает в момент, когда основной поток (UI thread) занят тяжелой операцией и не успевает обрабатывать события от системы.
Причины возникновения
- Долгие вычисления на главном потоке — например, сложный математический алгоритм, обработка изображений или криптографические операции без переноса в фон.
- Блокирующие сетевые запросы — прямой вызов
HttpURLConnectionилиOkHttpна главном потоке без использования асинхронности. - Блокировка базы данных — тяжелые запросы к SQLite или Room без использования
AsyncTask,CoroutinesилиWorkManager. - Интенсивная работа с виджетами — создание сложныхlayout’ов, многократные вызовы
inflateили использование тяжелых кастомных View без кэширования. - Неочищенные потоки и ресурсы — утечки памяти или незакрытые потоки, которые накапливают состояние и eventually блокируют главный поток.
Способы решения
Способ 1: Анализ логов и профилирование
Первое, что нужно сделать — выявить источник блокировки.
adb logcat *:s ANR:*
Откройте Android Studio Logcat, примените фильтр ANR, и вы увидите трассировку стека, где главный поток находится в ожидании более 5 секунд. Обратите внимание на имена классов и строки кода — это и есть «виновники».
Способ 2: Перенос тяжелых задач в фон
Перенесите все операции, которые занимают больше пары миллисекунд, за пределы главного потока.
Пример с Kotlin Coroutines:
lifecycleScope.launch {
withContext(Dispatchers.IO) {
// Тяжелая операция: загрузка файла, сетевой запрос, работа с БД
val data = fetchDataFromServer()
withContext(Dispatchers.Main) {
// Обновление UI после завершения
textView.text = data
}
}
}
Использование WorkManager, Thread или Executor гарантирует, что система не будет считать приложение «неотвечающим».
Способ 3: Оптимизация UI‑потока
Сократите объем работы, который главный поток выполняет каждый кадр.
- Используйте RecyclerView с view‑holder’ами вместо
ListView. - Избегайте тяжелых расчетов в методе
onDraw— переносите графику в отдельный слой или используйте Canvas с кэшированием. - Минимизируйте вызов
findViewById; используйте аннотацию @ViewById или биндинг(view binding). - Включайте StrictMode при разработке, чтобы получать предупреждения о блокирующих операциях.
Способ 4: Обновление и очистка ресурсов
Иногда ANR вызывают устаревшие библиотеки или поврежденные кэш‑файлы.
- Обновите приложение до последней версии из Google Play — разработчики часто выпускают патчи, исправляющие ошибки производительности.
- Очистите кэш и данные приложения:
- Перейдите в Настройки → Приложения → Ваше приложение → Очистить кэш.
- При необходимости нажмите Очистить данные (будет сброшены настройки, но проблема уйдет, если она вызвана коррупцией кэша).
Способ 5: Переустановка приложения
Если вышеуказанные методы не помогли, выполните полную переустановку:
- Удалите приложение с устройства.
- Перезагрузите устройство.
- Установите приложение заново из магазина или с помощью Android Studio.
После переустановки проверьте, повторяется ли ошибка ANR.
Профилактика
- Всегда используйте асинхронные механизмы (Coroutines, RxJava, WorkManager) для сетевых запросов и работы с базой данных.
- Пишите unit‑тесты и интеграционные тесты, которые проверяют отклик UI под нагрузкой.
- Регулярно профилируйте приложение с помощью Android Studio Profiler и Systrace, чтобы находить «узкие места» до выхода обновления.
- Следите за версиями Android и обновляйте целевой SDK (
targetSdkVersion), чтобы использовать последние оптимизации системы. - Избегайте блокировок на главном потоке даже при коротких операциях — выносите даже простые задачи в фон, если они выполняются в цикле или под высокой нагрузкой.