В этом документе описывается, как система Android определяет, не отвечает ли приложение, и показано, как обеспечить отзывчивость вашего приложения.
Независимо от того, насколько хорошо написан ваш код, ваше приложение может работать медленно, зависать, зависать на значительные периоды времени или слишком долго обрабатывать вводимые данные. Если ваше приложение находится на переднем плане и не отвечает, пользователь получает диалоговое окно «Приложение не отвечает» (ANR), как показано на рисунке 1. Диалоговое окно ANR позволяет пользователю принудительно закрыть приложение. Если приложение не на переднем плане, оно автоматически останавливается. Крайне важно обеспечить адаптивность вашего приложения, чтобы свести к минимуму количество диалоговых окон ANR.
Триггеры ANR
Как правило, система отображает сообщение ANR, если приложение не может ответить на ввод пользователя в основном потоке, также известном как поток пользовательского интерфейса, что не позволяет системе обрабатывать входящие события пользовательского ввода.
Например, ошибка ANR может возникнуть, если приложение выполняет операцию блокировки ввода-вывода, например доступ к сети, в потоке пользовательского интерфейса. Другой пример: приложение тратит слишком много времени на создание сложной структуры в памяти или вычисление следующего хода в игре в потоке пользовательского интерфейса.
В Android скорость реагирования приложений контролируется системными службами ActivityManager
и WindowManager
. Android отображает диалоговое окно ANR для приложения, когда оно обнаруживает одно из следующих условий:
- Отсутствие реакции на событие ввода, например нажатие клавиши или касание экрана, в течение 5 секунд.
-
BroadcastReceiver
не завершает выполнение в течение 10–20 секунд для целей переднего плана. Дополнительные сведения см. в разделе Тайм-аут широковещательного приемника .
Избегайте ошибок ANR
Ниже приведены общие советы по предотвращению ошибок ANR. Дополнительные сведения о диагностике и отладке различных типов ошибок ANR см. на других страницах этого раздела.
Постоянно держите основной поток разблокированным и используйте потоки стратегически.
Не выполняйте блокирующие или длительные операции в основном потоке приложения. Вместо этого создайте рабочий поток и выполняйте большую часть работы там.
Постарайтесь свести к минимуму любые конфликты блокировок между основным потоком и другими потоками.
Сведите к минимуму любую работу, не связанную с пользовательским интерфейсом, в основном потоке, например, при обработке широковещательных рассылок или запуске служб. Любой метод, выполняющийся в потоке пользовательского интерфейса, должен выполнять в этом потоке как можно меньше работы. В частности, действия должны выполнять как можно меньше действий для настройки в ключевых методах жизненного цикла, таких как
onCreate()
иonResume()
. Дополнительные сведения о доступных решениях для планирования работы в фоновом потоке и обратной связи с пользовательским интерфейсом см. в разделе Обзор фоновой работы.Будьте осторожны при совместном использовании пулов потоков между компонентами. Не используйте одни и те же потоки для потенциально длительных операций блокировки и задач, чувствительных ко времени, таких как прием широковещательных сообщений.
Обеспечьте быстрый запуск приложения. Минимизируйте медленные или блокирующие операции в коде запуска приложения, например методы, запускаемые во время инициализации кинжала.
Если вы используете
BroadcastReceiver
, рассмотрите возможность запуска широковещательных приемников в неосновном потоке с помощьюContext.registerReceiver
. Дополнительные сведения см. в разделе ANR в BroadcastReceiver .- Если вы используете
goAsync()
, убедитесь, чтоPendingResult.finish
вызывается быстро до истечения времени ожидания ANR.
- Если вы используете
Ошибки ANR в BroadcastReceiver
Время выполнения BroadcastReceiver
ограничено, поскольку приемники широковещательных сообщений предназначены для выполнения небольших дискретных объемов работы в фоновом режиме, таких как сохранение настроек или регистрация Notification
. Таким образом, как и в случае с другими методами, вызываемыми в потоке пользовательского интерфейса, приложениям следует избегать потенциально длительных операций или вычислений в широковещательном приемнике. Вместо выполнения длительных задач через поток пользовательского интерфейса выполняйте их в фоновом режиме для последующего выполнения. См. Обзор фоновой работы для получения дополнительной информации о возможных решениях.
Другая распространенная проблема с объектами BroadcastReceiver
возникает, когда они выполняются слишком часто. Частое выполнение в фоновом режиме может уменьшить объем памяти, доступной другим приложениям. Дополнительные сведения о том, как эффективно включать и отключать объекты BroadcastReceiver
, см. в разделе Обзор широковещательных рассылок .
Повысьте оперативность
Обычно от 100 до 200 мс — это порог, за которым пользователи воспринимают замедление работы приложения. Вот дополнительные советы, как сделать ваше приложение более отзывчивым для пользователей:
Если ваше приложение выполняет работу в фоновом режиме в ответ на ввод пользователя, покажите, что прогресс достигается, например, с помощью
ProgressBar
в вашем пользовательском интерфейсе.В частности, в играх расчеты ходов выполняются в рабочем потоке.
Если этап начальной настройки вашего приложения занимает много времени, рассмотрите возможность отображения заставки или рендеринга основного вида как можно быстрее. Укажите, что идет загрузка, и заполните информацию асинхронно. В любом случае мы рекомендуем каким-либо образом указать, что прогресс выполняется, чтобы пользователь не заметил, что приложение зависло.
Используйте инструменты производительности, такие как Perfetto и CPU Profiler, чтобы определить узкие места в скорости отклика вашего приложения.
В этом документе описывается, как система Android определяет, не отвечает ли приложение, и показано, как обеспечить отзывчивость вашего приложения.
Независимо от того, насколько хорошо написан ваш код, ваше приложение может работать медленно, зависать, зависать на значительные периоды времени или слишком долго обрабатывать вводимые данные. Если ваше приложение находится на переднем плане и не отвечает, пользователь получает диалоговое окно «Приложение не отвечает» (ANR), как показано на рисунке 1. Диалоговое окно ANR позволяет пользователю принудительно закрыть приложение. Если приложение не на переднем плане, оно автоматически останавливается. Крайне важно обеспечить адаптивность вашего приложения, чтобы свести к минимуму количество диалоговых окон ANR.
Триггеры ANR
Как правило, система отображает сообщение ANR, если приложение не может ответить на ввод пользователя в основном потоке, также известном как поток пользовательского интерфейса, что не позволяет системе обрабатывать входящие события пользовательского ввода.
Например, ошибка ANR может возникнуть, если приложение выполняет операцию блокировки ввода-вывода, например доступ к сети, в потоке пользовательского интерфейса. Другой пример — когда приложение тратит слишком много времени на создание сложной структуры в памяти или вычисление следующего хода в игре в потоке пользовательского интерфейса.
В Android скорость реагирования приложений контролируется системными службами ActivityManager
и WindowManager
. Android отображает диалоговое окно ANR для приложения, когда оно обнаруживает одно из следующих условий:
- Отсутствие реакции на событие ввода, например нажатие клавиши или касание экрана, в течение 5 секунд.
-
BroadcastReceiver
не завершает выполнение в течение 10–20 секунд для целей переднего плана. Дополнительные сведения см. в разделе Тайм-аут широковещательного приемника .
Избегайте ошибок ANR
Ниже приведены общие советы по предотвращению ошибок ANR. Дополнительные сведения о диагностике и отладке различных типов ошибок ANR см. на других страницах этого раздела.
Постоянно держите основной поток разблокированным и используйте потоки стратегически.
Не выполняйте блокирующие или длительные операции в основном потоке приложения. Вместо этого создайте рабочий поток и выполняйте большую часть работы там.
Постарайтесь свести к минимуму любые конфликты блокировок между основным потоком и другими потоками.
Сведите к минимуму любую работу, не связанную с пользовательским интерфейсом, в основном потоке, например, при обработке широковещательных рассылок или запуске служб. Любой метод, выполняющийся в потоке пользовательского интерфейса, должен выполнять в этом потоке как можно меньше работы. В частности, действия должны выполнять как можно меньше действий для настройки в ключевых методах жизненного цикла, таких как
onCreate()
иonResume()
. Дополнительные сведения о доступных решениях для планирования работы в фоновом потоке и обратной связи с пользовательским интерфейсом см. в разделе Обзор фоновой работы.Будьте осторожны при совместном использовании пулов потоков между компонентами. Не используйте одни и те же потоки для потенциально длительных операций блокировки и задач, чувствительных ко времени, таких как прием широковещательных сообщений.
Обеспечьте быстрый запуск приложения. Минимизируйте медленные или блокирующие операции в коде запуска приложения, например методы, запускаемые во время инициализации кинжала.
Если вы используете
BroadcastReceiver
, рассмотрите возможность запуска широковещательных приемников в неосновном потоке с помощьюContext.registerReceiver
. Дополнительные сведения см. в разделе ANR в BroadcastReceiver .- Если вы используете
goAsync()
, убедитесь, чтоPendingResult.finish
вызывается быстро до истечения времени ожидания ANR.
- Если вы используете
Ошибки ANR в BroadcastReceiver
Время выполнения BroadcastReceiver
ограничено, поскольку приемники широковещательных сообщений предназначены для выполнения небольших дискретных объемов работы в фоновом режиме, таких как сохранение настроек или регистрация Notification
. Таким образом, как и в случае с другими методами, вызываемыми в потоке пользовательского интерфейса, приложениям следует избегать потенциально длительных операций или вычислений в широковещательном приемнике. Вместо выполнения длительных задач через поток пользовательского интерфейса выполняйте их в фоновом режиме для последующего выполнения. См. Обзор фоновой работы для получения дополнительной информации о возможных решениях.
Другая распространенная проблема с объектами BroadcastReceiver
возникает, когда они выполняются слишком часто. Частое выполнение в фоновом режиме может уменьшить объем памяти, доступной другим приложениям. Дополнительные сведения о том, как эффективно включать и отключать объекты BroadcastReceiver
, см. в разделе Обзор широковещательных рассылок .
Повысьте оперативность
Обычно от 100 до 200 мс — это порог, за которым пользователи воспринимают замедление работы приложения. Вот дополнительные советы, как сделать ваше приложение более отзывчивым для пользователей:
Если ваше приложение выполняет работу в фоновом режиме в ответ на ввод пользователя, покажите, что прогресс достигается, например, с помощью
ProgressBar
в вашем пользовательском интерфейсе.В частности, в играх расчеты ходов выполняются в рабочем потоке.
Если этап начальной настройки вашего приложения занимает много времени, рассмотрите возможность отображения заставки или рендеринга основного вида как можно быстрее. Укажите, что идет загрузка, и заполните информацию асинхронно. В любом случае мы рекомендуем каким-либо образом указать, что прогресс выполняется, чтобы пользователь не заметил, что приложение зависло.
Используйте инструменты повышения производительности, такие как Perfetto и CPU Profiler, чтобы определить узкие места в скорости отклика вашего приложения.