ANR

Когда поток пользовательского интерфейса Android-приложения блокируется слишком долго, возникает ошибка «Приложение не отвечает» (ANR). Если приложение находится на переднем плане, система отображает пользователю диалоговое окно, как показано на рисунке 1. Диалоговое окно ANR предоставляет пользователю возможность принудительно завершить работу приложения.

Пользователю отображается диалоговое окно ANR.
Рисунок 1. Диалоговое окно ANR, отображаемое пользователю.

Проблемы с ANR возникают из-за того, что основной поток приложения, отвечающий за обновление пользовательского интерфейса, не может обрабатывать события ввода пользователя или отрисовывать изображение, что вызывает у пользователя раздражение. Более подробную информацию об основном потоке приложения см. в разделе «Обзор процессов и потоков» .

Событие ANR срабатывает для вашего приложения при возникновении одного из следующих условий:

  • Истекло время ожидания ответа на ввод: если ваше приложение не отреагировало на событие ввода (например, нажатие клавиши или касание экрана) в течение 5 секунд.
  • Выполнение службы: Если служба, объявленная вашим приложением, не может завершить выполнение Service.onCreate и Service.onStartCommand / Service.onBind в течение нескольких секунд.
  • Service.startForeground не вызывается: Если ваше приложение использует Context.startForegroundService для запуска новой службы на переднем плане, но служба не вызывает startForeground в течение 5 секунд.
  • Трансляция намерения: Если BroadcastReceiver не завершил выполнение в течение заданного промежутка времени. Если в приложении есть какая-либо активность на переднем плане, этот тайм-аут составляет 5 секунд.
  • Взаимодействие JobScheduler : Если JobService не возвращает управление из JobService.onStartJob или JobService.onStopJob в течение нескольких секунд, или если запускается инициированное пользователем задание , а ваше приложение не вызывает JobService.setNotification в течение нескольких секунд после вызова JobService.onStartJob . Для приложений, ориентированных на Android 13 и ниже, сообщения об ошибках (ANR) не отображаются и не передаются приложению. Для приложений, ориентированных на Android 14 и выше, сообщения об ошибках (ANR) отображаются явно и передаются приложению.

Если в вашем приложении возникают ошибки ANR (Anti-Resources — неработающие приложения), вы можете воспользоваться рекомендациями в этом документе для диагностики и устранения проблемы.

Диагностика ANR

При диагностике ОНР следует обращать внимание на некоторые общие закономерности:

  • Приложение выполняет медленные операции ввода-вывода в основном потоке.
  • Приложение выполняет длительные вычисления в основном потоке.
  • Основной поток выполняет синхронный вызов функции связывания к другому процессу, и этот другой процесс долго возвращает результат.
  • Основной поток заблокирован в ожидании синхронизированной блокировки для длительной операции, которая выполняется в другом потоке.
  • Основной поток находится в тупиковой ситуации с другим потоком, либо в вашем процессе, либо из-за вызова связывателя. Основной поток не просто ожидает завершения длительной операции, а находится в тупиковой ситуации.

Следующие методы помогут вам определить причину ваших нарушений дыхания во сне.

HealthStats

HealthStats предоставляет метрики о состоянии приложения, фиксируя общее время работы пользователя и системы, время работы процессора, сетевые и радиоданные, время включения/выключения экрана и сигналы пробуждения. Это может помочь измерить общую загрузку процессора и разрядку батареи.

Отлаживать

Debug помогает проверять приложения Android во время разработки, включая трассировку и подсчет выделенной памяти для выявления рывков и задержек в работе приложений. Вы также можете использовать Debug для получения счетчиков памяти во время выполнения и в нативной памяти, а также метрик памяти, которые помогут определить объем памяти, занимаемый конкретным процессом.

ApplicationExitInfo

ApplicationExitInfo доступна в Android 11 (уровень API 30) и выше и предоставляет информацию о причине завершения работы приложения. Сюда входят ошибки ANR, нехватка памяти, сбои приложения, чрезмерное использование ЦП, прерывания со стороны пользователя, системные сбои и изменения разрешений во время выполнения.

Строгий режим

Использование StrictMode помогает обнаруживать случайные операции ввода-вывода в основном потоке во время разработки приложения. Вы можете использовать StrictMode на уровне приложения или активности.

Включить фоновые диалоги ANR

Android отображает диалоговые окна ANR для приложений, которые слишком долго обрабатывают широковещательное сообщение, только если в параметрах разработчика устройства включена опция «Показывать все ANR» . По этой причине фоновые диалоговые окна ANR не всегда отображаются пользователю, даже когда приложение испытывает проблемы с производительностью.

Узкие места рекомпозиции

Используйте профилировщик Android Studio и инспектор макетов , чтобы выявить узкие места, влияющие на производительность при создании композиции. Дополнительную информацию см. в разделе «Производительность Jetpack Compose» .

Загрузите файл трассировки.

Android сохраняет информацию о трассировке при возникновении ANR. В более старых версиях ОС на устройстве находится один файл /data/anr/traces.txt . В более новых версиях ОС существует несколько файлов /data/anr/anr_* . Вы можете получить доступ к трассировке ANR с устройства или эмулятора, используя Android Debug Bridge (adb) от имени root:

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

Вы можете получить отчет об ошибке с физического устройства, используя либо опцию «Получить отчет об ошибке» на устройстве, либо команду adb bugreport на вашей машине разработки. Для получения дополнительной информации см. раздел «Получение и чтение отчетов об ошибках» .

Устраните проблемы

После того, как вы определили проблему, вы можете использовать советы из этого раздела для устранения распространенных неполадок.

Медленная работа кода в основном потоке.

Определите места в вашем коде, где основной поток приложения занят более 5 секунд. Найдите подозрительные сценарии использования в вашем приложении и попробуйте воспроизвести ошибку ANR.

Распространенная проблема — это длительно выполняющаяся задача, находящаяся непосредственно в составном объекте:

@Composable
fun BadList(rawStrings: List<String>) {
    // Math or sorting inside the composable runs on EVERY recomposition pass!
    val heavilyProcessedList = rawStrings
        .filter { it.isNotBlank() }
        .map { it.uppercase().reversed() }
        .map { it.computationallyHeavyFunction() }
.sortedBy { it.length }
    LazyColumn { items(sortedList) { Text(it) } }
}

// Modern Compose-first fix
@Composable
fun GoodList(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    // UI simply renders state; no heavy processing allowed here
    LazyColumn { items(uiState.sortedData) { Text(it) } }
}

Ввод-вывод в основном потоке

Выполнение операций ввода-вывода в основном потоке является распространенной причиной замедления работы основного потока, что может привести к ошибкам ANR. В Compose разработчики часто случайно запускают операции чтения с диска (например, SharedPreferences или вызовы к базе данных) при попытке определить начальное состояние.

Выполняйте длительные операции ввода-вывода вне уровня пользовательского интерфейса. Используйте withContext(Dispatchers.IO) в ViewModel или, что еще лучше, используйте Repository на уровне данных .

Тупиковые ситуации

Взаимная блокировка возникает, когда поток переходит в состояние ожидания, поскольку необходимый ресурс удерживается другим потоком, который также ожидает ресурс, удерживаемый первым потоком. Если основной поток приложения находится в такой ситуации, высока вероятность возникновения ошибок ANR.

Взаимоблокировки — хорошо изученное явление в информатике, и существуют алгоритмы предотвращения взаимоблокировок, которые можно использовать для их избежания.

Для получения более подробной информации см. раздел «Взаимная блокировка и алгоритмы предотвращения взаимоблокировок» в Википедии.

При использовании Kotlin и Compose вы можете заменить примитивные блокировки неблокирующими сопрограммами-мьютексами ( Mutex.withLock ), чтобы предотвратить блокировку потоков, приостанавливая контекст выполнения вместо замораживания потока пользовательского интерфейса. Например:

import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

// Modern non-blocking concurrency state architecture
class SecureDataRepository {
    private val mutex = Mutex()

    suspend fun safeUIAccess() {
        // If locked, the main thread suspends seamlessly, preventing an ANR
        mutex.withLock {
            performSafeOperation()
        }
    }
}

Медленные приемники вещания

Приложения могут реагировать на широковещательные сообщения, такие как включение или выключение режима полета или изменение состояния подключения, с помощью широковещательных приемников. Ошибка ANR возникает, когда приложению требуется слишком много времени для обработки широковещательного сообщения.

Ангионервная регургитация возникает в следующих случаях:

  • Приёмник широковещательной рассылки не завершил выполнение своего метода onReceive в течение значительного промежутка времени.
  • Приемник широковещательной рассылки вызывает goAsync , но не может вызвать finish для объекта PendingResult .

В методе onReceive объекта BroadcastReceiver ваше приложение должно выполнять только короткие операции. Однако, если вашему приложению требуется более сложная обработка в результате широковещательного сообщения, следует отложить задачу до ViewModel (используя возможности корутин, областей видимости и диспетчеров Kotlin), если ожидается, что задача займет не более нескольких секунд, до любого типа хранилища состояния или до WorkManager для задач, ожидаемых на выполнение дольше нескольких секунд.

Игровая активность

Библиотека GameActivity позволила сократить количество ошибок ANR в тестах игр и приложений, написанных на C или C++. Заменив существующую нативную активность на GameActivity , вы сможете уменьшить блокировку потоков пользовательского интерфейса и предотвратить возникновение некоторых ошибок ANR.

Для получения дополнительной информации об ANR см. раздел «Обеспечение отзывчивости приложения» . Для получения дополнительной информации о потоках см. раздел «Повышение производительности за счет многопоточности» .

Дополнительные ресурсы

Просмотры контента

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %} ,

Когда поток пользовательского интерфейса Android-приложения блокируется слишком долго, возникает ошибка «Приложение не отвечает» (ANR). Если приложение находится на переднем плане, система отображает пользователю диалоговое окно, как показано на рисунке 1. Диалоговое окно ANR предоставляет пользователю возможность принудительно завершить работу приложения.

Пользователю отображается диалоговое окно ANR.
Рисунок 1. Диалоговое окно ANR, отображаемое пользователю.

Проблемы с ANR возникают из-за того, что основной поток приложения, отвечающий за обновление пользовательского интерфейса, не может обрабатывать события ввода пользователя или отрисовывать изображение, что вызывает у пользователя раздражение. Более подробную информацию об основном потоке приложения см. в разделе «Обзор процессов и потоков» .

Событие ANR срабатывает для вашего приложения при возникновении одного из следующих условий:

  • Истекло время ожидания ответа на ввод: если ваше приложение не отреагировало на событие ввода (например, нажатие клавиши или касание экрана) в течение 5 секунд.
  • Выполнение службы: Если служба, объявленная вашим приложением, не может завершить выполнение Service.onCreate и Service.onStartCommand / Service.onBind в течение нескольких секунд.
  • Service.startForeground не вызывается: Если ваше приложение использует Context.startForegroundService для запуска новой службы на переднем плане, но служба не вызывает startForeground в течение 5 секунд.
  • Трансляция намерения: Если BroadcastReceiver не завершил выполнение в течение заданного промежутка времени. Если в приложении есть какая-либо активность на переднем плане, этот тайм-аут составляет 5 секунд.
  • Взаимодействие JobScheduler : Если JobService не возвращает управление из JobService.onStartJob или JobService.onStopJob в течение нескольких секунд, или если запускается инициированное пользователем задание , а ваше приложение не вызывает JobService.setNotification в течение нескольких секунд после вызова JobService.onStartJob . Для приложений, ориентированных на Android 13 и ниже, сообщения об ошибках (ANR) не отображаются и не передаются приложению. Для приложений, ориентированных на Android 14 и выше, сообщения об ошибках (ANR) отображаются явно и передаются приложению.

Если в вашем приложении возникают ошибки ANR (Anti-Resources — неработающие приложения), вы можете воспользоваться рекомендациями в этом документе для диагностики и устранения проблемы.

Диагностика ANR

При диагностике ОНР следует обращать внимание на некоторые общие закономерности:

  • Приложение выполняет медленные операции ввода-вывода в основном потоке.
  • Приложение выполняет длительные вычисления в основном потоке.
  • Основной поток выполняет синхронный вызов функции связывания к другому процессу, и этот другой процесс долго возвращает результат.
  • Основной поток заблокирован в ожидании синхронизированной блокировки для длительной операции, которая выполняется в другом потоке.
  • Основной поток находится в тупиковой ситуации с другим потоком, либо в вашем процессе, либо из-за вызова связывателя. Основной поток не просто ожидает завершения длительной операции, а находится в тупиковой ситуации.

Следующие методы помогут вам определить причину ваших нарушений дыхания во сне.

HealthStats

HealthStats предоставляет метрики о состоянии приложения, фиксируя общее время работы пользователя и системы, время работы процессора, сетевые и радиоданные, время включения/выключения экрана и сигналы пробуждения. Это может помочь измерить общую загрузку процессора и разрядку батареи.

Отлаживать

Debug помогает проверять приложения Android во время разработки, включая трассировку и подсчет выделенной памяти для выявления рывков и задержек в работе приложений. Вы также можете использовать Debug для получения счетчиков памяти во время выполнения и в нативной памяти, а также метрик памяти, которые помогут определить объем памяти, занимаемый конкретным процессом.

ApplicationExitInfo

ApplicationExitInfo доступна в Android 11 (уровень API 30) и выше и предоставляет информацию о причине завершения работы приложения. Сюда входят ошибки ANR, нехватка памяти, сбои приложения, чрезмерное использование ЦП, прерывания со стороны пользователя, системные сбои и изменения разрешений во время выполнения.

Строгий режим

Использование StrictMode помогает обнаруживать случайные операции ввода-вывода в основном потоке во время разработки приложения. Вы можете использовать StrictMode на уровне приложения или активности.

Включить фоновые диалоги ANR

Android отображает диалоговые окна ANR для приложений, которые слишком долго обрабатывают широковещательное сообщение, только если в параметрах разработчика устройства включена опция «Показывать все ANR» . По этой причине фоновые диалоговые окна ANR не всегда отображаются пользователю, даже когда приложение испытывает проблемы с производительностью.

Узкие места рекомпозиции

Используйте профилировщик Android Studio и инспектор макетов , чтобы выявить узкие места, влияющие на производительность при создании композиции. Дополнительную информацию см. в разделе «Производительность Jetpack Compose» .

Загрузите файл трассировки.

Android сохраняет информацию о трассировке при возникновении ANR. В более старых версиях ОС на устройстве находится один файл /data/anr/traces.txt . В более новых версиях ОС существует несколько файлов /data/anr/anr_* . Вы можете получить доступ к трассировке ANR с устройства или эмулятора, используя Android Debug Bridge (adb) от имени root:

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

Вы можете получить отчет об ошибке с физического устройства, используя либо опцию «Получить отчет об ошибке» на устройстве, либо команду adb bugreport на вашей машине разработки. Для получения дополнительной информации см. раздел «Получение и чтение отчетов об ошибках» .

Устраните проблемы

После того, как вы определили проблему, вы можете использовать советы из этого раздела для устранения распространенных неполадок.

Медленная работа кода в основном потоке.

Определите места в вашем коде, где основной поток приложения занят более 5 секунд. Найдите подозрительные сценарии использования в вашем приложении и попробуйте воспроизвести ошибку ANR.

Распространенная проблема — это длительно выполняющаяся задача, находящаяся непосредственно в составном объекте:

@Composable
fun BadList(rawStrings: List<String>) {
    // Math or sorting inside the composable runs on EVERY recomposition pass!
    val heavilyProcessedList = rawStrings
        .filter { it.isNotBlank() }
        .map { it.uppercase().reversed() }
        .map { it.computationallyHeavyFunction() }
.sortedBy { it.length }
    LazyColumn { items(sortedList) { Text(it) } }
}

// Modern Compose-first fix
@Composable
fun GoodList(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    // UI simply renders state; no heavy processing allowed here
    LazyColumn { items(uiState.sortedData) { Text(it) } }
}

Ввод-вывод в основном потоке

Выполнение операций ввода-вывода в основном потоке является распространенной причиной замедления работы основного потока, что может привести к ошибкам ANR. В Compose разработчики часто случайно запускают операции чтения с диска (например, SharedPreferences или вызовы к базе данных) при попытке определить начальное состояние.

Выполняйте длительные операции ввода-вывода вне уровня пользовательского интерфейса. Используйте withContext(Dispatchers.IO) в ViewModel или, что еще лучше, используйте Repository на уровне данных .

Тупиковые ситуации

Взаимная блокировка возникает, когда поток переходит в состояние ожидания, поскольку необходимый ресурс удерживается другим потоком, который также ожидает ресурс, удерживаемый первым потоком. Если основной поток приложения находится в такой ситуации, высока вероятность возникновения ошибок ANR.

Взаимоблокировки — хорошо изученное явление в информатике, и существуют алгоритмы предотвращения взаимоблокировок, которые можно использовать для их избежания.

Для получения более подробной информации см. раздел «Взаимная блокировка и алгоритмы предотвращения взаимоблокировок» в Википедии.

При использовании Kotlin и Compose вы можете заменить примитивные блокировки неблокирующими сопрограммами-мьютексами ( Mutex.withLock ), чтобы предотвратить блокировку потоков, приостанавливая контекст выполнения вместо замораживания потока пользовательского интерфейса. Например:

import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

// Modern non-blocking concurrency state architecture
class SecureDataRepository {
    private val mutex = Mutex()

    suspend fun safeUIAccess() {
        // If locked, the main thread suspends seamlessly, preventing an ANR
        mutex.withLock {
            performSafeOperation()
        }
    }
}

Медленные приемники вещания

Приложения могут реагировать на широковещательные сообщения, такие как включение или выключение режима полета или изменение состояния подключения, с помощью широковещательных приемников. Ошибка ANR возникает, когда приложению требуется слишком много времени для обработки широковещательного сообщения.

Ангионервная регургитация возникает в следующих случаях:

  • Приёмник широковещательной рассылки не завершил выполнение своего метода onReceive в течение значительного промежутка времени.
  • Приемник широковещательной рассылки вызывает goAsync , но не может вызвать finish для объекта PendingResult .

В методе onReceive объекта BroadcastReceiver ваше приложение должно выполнять только короткие операции. Однако, если вашему приложению требуется более сложная обработка в результате широковещательного сообщения, следует отложить задачу до ViewModel (используя возможности корутин, областей видимости и диспетчеров Kotlin), если ожидается, что задача займет не более нескольких секунд, до любого типа хранилища состояния или до WorkManager для задач, ожидаемых на выполнение дольше нескольких секунд.

Игровая активность

Библиотека GameActivity позволила сократить количество ошибок ANR в тестах игр и приложений, написанных на C или C++. Заменив существующую нативную активность на GameActivity , вы сможете уменьшить блокировку потоков пользовательского интерфейса и предотвратить возникновение некоторых ошибок ANR.

Для получения дополнительной информации об ANR см. раздел «Обеспечение отзывчивости приложения» . Для получения дополнительной информации о потоках см. раздел «Повышение производительности за счет многопоточности» .

Дополнительные ресурсы

Просмотры контента

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %} ,

Когда поток пользовательского интерфейса Android-приложения блокируется слишком долго, возникает ошибка «Приложение не отвечает» (ANR). Если приложение находится на переднем плане, система отображает пользователю диалоговое окно, как показано на рисунке 1. Диалоговое окно ANR предоставляет пользователю возможность принудительно завершить работу приложения.

Пользователю отображается диалоговое окно ANR.
Рисунок 1. Диалоговое окно ANR, отображаемое пользователю.

Проблемы с ANR возникают из-за того, что основной поток приложения, отвечающий за обновление пользовательского интерфейса, не может обрабатывать события ввода пользователя или отрисовывать изображение, что вызывает у пользователя раздражение. Более подробную информацию об основном потоке приложения см. в разделе «Обзор процессов и потоков» .

Событие ANR срабатывает для вашего приложения при возникновении одного из следующих условий:

  • Истекло время ожидания ответа на ввод: если ваше приложение не отреагировало на событие ввода (например, нажатие клавиши или касание экрана) в течение 5 секунд.
  • Выполнение службы: Если служба, объявленная вашим приложением, не может завершить выполнение Service.onCreate и Service.onStartCommand / Service.onBind в течение нескольких секунд.
  • Service.startForeground не вызывается: Если ваше приложение использует Context.startForegroundService для запуска новой службы на переднем плане, но служба не вызывает startForeground в течение 5 секунд.
  • Трансляция намерения: Если BroadcastReceiver не завершил выполнение в течение заданного промежутка времени. Если в приложении есть какая-либо активность на переднем плане, этот тайм-аут составляет 5 секунд.
  • Взаимодействие JobScheduler : Если JobService не возвращает управление из JobService.onStartJob или JobService.onStopJob в течение нескольких секунд, или если запускается инициированное пользователем задание , а ваше приложение не вызывает JobService.setNotification в течение нескольких секунд после вызова JobService.onStartJob . Для приложений, ориентированных на Android 13 и ниже, сообщения об ошибках (ANR) не отображаются и не передаются приложению. Для приложений, ориентированных на Android 14 и выше, сообщения об ошибках (ANR) отображаются явно и передаются приложению.

Если в вашем приложении возникают ошибки ANR (Anti-Resources — неработающие приложения), вы можете воспользоваться рекомендациями в этом документе для диагностики и устранения проблемы.

Диагностика ANR

При диагностике ОНР следует обращать внимание на некоторые общие закономерности:

  • Приложение выполняет медленные операции ввода-вывода в основном потоке.
  • Приложение выполняет длительные вычисления в основном потоке.
  • Основной поток выполняет синхронный вызов функции связывания к другому процессу, и этот другой процесс долго возвращает результат.
  • Основной поток заблокирован в ожидании синхронизированной блокировки для длительной операции, которая выполняется в другом потоке.
  • Основной поток находится в тупиковой ситуации с другим потоком, либо в вашем процессе, либо из-за вызова связывателя. Основной поток не просто ожидает завершения длительной операции, а находится в тупиковой ситуации.

Следующие методы помогут вам определить причину ваших нарушений дыхания во сне.

HealthStats

HealthStats предоставляет метрики о состоянии приложения, фиксируя общее время работы пользователя и системы, время работы процессора, сетевые и радиоданные, время включения/выключения экрана и сигналы пробуждения. Это может помочь измерить общую загрузку процессора и разрядку батареи.

Отлаживать

Debug помогает проверять приложения Android во время разработки, включая трассировку и подсчет выделенной памяти для выявления рывков и задержек в работе приложений. Вы также можете использовать Debug для получения счетчиков памяти во время выполнения и в нативной памяти, а также метрик памяти, которые помогут определить объем памяти, занимаемый конкретным процессом.

ApplicationExitInfo

ApplicationExitInfo доступна в Android 11 (уровень API 30) и выше и предоставляет информацию о причине завершения работы приложения. Сюда входят ошибки ANR, нехватка памяти, сбои приложения, чрезмерное использование ЦП, прерывания со стороны пользователя, системные сбои и изменения разрешений во время выполнения.

Строгий режим

Использование StrictMode помогает обнаруживать случайные операции ввода-вывода в основном потоке во время разработки приложения. Вы можете использовать StrictMode на уровне приложения или активности.

Включить фоновые диалоги ANR

Android отображает диалоговые окна ANR для приложений, которые слишком долго обрабатывают широковещательное сообщение, только если в параметрах разработчика устройства включена опция «Показывать все ANR» . По этой причине фоновые диалоговые окна ANR не всегда отображаются пользователю, даже когда приложение испытывает проблемы с производительностью.

Узкие места рекомпозиции

Используйте профилировщик Android Studio и инспектор макетов , чтобы выявить узкие места, влияющие на производительность при создании композиции. Дополнительную информацию см. в разделе «Производительность Jetpack Compose» .

Загрузите файл трассировки.

Android сохраняет информацию о трассировке при возникновении ANR. В более старых версиях ОС на устройстве находится один файл /data/anr/traces.txt . В более новых версиях ОС существует несколько файлов /data/anr/anr_* . Вы можете получить доступ к трассировке ANR с устройства или эмулятора, используя Android Debug Bridge (adb) от имени root:

adb root
adb shell ls /data/anr
adb pull /data/anr/<filename>

Вы можете получить отчет об ошибке с физического устройства, используя либо опцию «Получить отчет об ошибке» на устройстве, либо команду adb bugreport на вашей машине разработки. Для получения дополнительной информации см. раздел «Получение и чтение отчетов об ошибках» .

Устраните проблемы

После того, как вы определили проблему, вы можете использовать советы из этого раздела для устранения распространенных неполадок.

Медленная работа кода в основном потоке.

Определите места в вашем коде, где основной поток приложения занят более 5 секунд. Найдите подозрительные сценарии использования в вашем приложении и попробуйте воспроизвести ошибку ANR.

Распространенная проблема — это длительно выполняющаяся задача, находящаяся непосредственно в составном объекте:

@Composable
fun BadList(rawStrings: List<String>) {
    // Math or sorting inside the composable runs on EVERY recomposition pass!
    val heavilyProcessedList = rawStrings
        .filter { it.isNotBlank() }
        .map { it.uppercase().reversed() }
        .map { it.computationallyHeavyFunction() }
.sortedBy { it.length }
    LazyColumn { items(sortedList) { Text(it) } }
}

// Modern Compose-first fix
@Composable
fun GoodList(viewModel: MyViewModel = viewModel()) {
    val uiState by viewModel.uiState.collectAsStateWithLifecycle()

    // UI simply renders state; no heavy processing allowed here
    LazyColumn { items(uiState.sortedData) { Text(it) } }
}

Ввод-вывод в основном потоке

Выполнение операций ввода-вывода в основном потоке является распространенной причиной замедления работы основного потока, что может привести к ошибкам ANR. В Compose разработчики часто случайно запускают операции чтения с диска (например, SharedPreferences или вызовы к базе данных) при попытке определить начальное состояние.

Выполняйте длительные операции ввода-вывода вне уровня пользовательского интерфейса. Используйте withContext(Dispatchers.IO) в ViewModel или, что еще лучше, используйте Repository на уровне данных .

Тупиковые ситуации

Взаимная блокировка возникает, когда поток переходит в состояние ожидания, поскольку необходимый ресурс удерживается другим потоком, который также ожидает ресурс, удерживаемый первым потоком. Если основной поток приложения находится в такой ситуации, высока вероятность возникновения ошибок ANR.

Взаимоблокировки — хорошо изученное явление в информатике, и существуют алгоритмы предотвращения взаимоблокировок, которые можно использовать для их избежания.

Для получения более подробной информации см. раздел «Взаимная блокировка и алгоритмы предотвращения взаимоблокировок» в Википедии.

При использовании Kotlin и Compose вы можете заменить примитивные блокировки неблокирующими сопрограммами-мьютексами ( Mutex.withLock ), чтобы предотвратить блокировку потоков, приостанавливая контекст выполнения вместо замораживания потока пользовательского интерфейса. Например:

import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock

// Modern non-blocking concurrency state architecture
class SecureDataRepository {
    private val mutex = Mutex()

    suspend fun safeUIAccess() {
        // If locked, the main thread suspends seamlessly, preventing an ANR
        mutex.withLock {
            performSafeOperation()
        }
    }
}

Медленные приемники вещания

Приложения могут реагировать на широковещательные сообщения, такие как включение или выключение режима полета или изменение состояния подключения, с помощью широковещательных приемников. Ошибка ANR возникает, когда приложению требуется слишком много времени для обработки широковещательного сообщения.

Ангионервная регургитация возникает в следующих случаях:

  • Приёмник широковещательной рассылки не завершил выполнение своего метода onReceive в течение значительного промежутка времени.
  • Приемник широковещательной рассылки вызывает goAsync , но не может вызвать finish для объекта PendingResult .

В методе onReceive объекта BroadcastReceiver ваше приложение должно выполнять только короткие операции. Однако, если вашему приложению требуется более сложная обработка в результате широковещательного сообщения, следует отложить задачу до ViewModel (используя возможности корутин, областей видимости и диспетчеров Kotlin), если ожидается, что задача займет не более нескольких секунд, до любого типа хранилища состояния или до WorkManager для задач, ожидаемых на выполнение дольше нескольких секунд.

Игровая активность

Библиотека GameActivity позволила сократить количество ошибок ANR в тестах игр и приложений, написанных на C или C++. Заменив существующую нативную активность на GameActivity , вы сможете уменьшить блокировку потоков пользовательского интерфейса и предотвратить возникновение некоторых ошибок ANR.

Для получения дополнительной информации об ANR см. раздел «Обеспечение отзывчивости приложения» . Для получения дополнительной информации о потоках см. раздел «Повышение производительности за счет многопоточности» .

Дополнительные ресурсы

Просмотры контента

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}