Понимание жизненного цикла Activity и роли ActivityThread
Activity — экран приложения; ActivityThread управляет созданием, вызовом callback-методов через очередь сообщений (Handler H) и Looper. Коротко: не блокируйте главный поток, освобождайте ресурсы и используйте lifecycle-aware компоненты — тогда ANR и утечки будут редкостью.
Что такое ActivityThread и как работает H (Handler)
ActivityThread — системный класс (android.app) в процессе приложения, который создаёт Looper/MessageQueue и обрабатывает события, связанные с жизненным циклом Activity. Система посылает сообщения (LAUNCH_ACTIVITY, PAUSE_ACTIVITY и т.д.) в очередь, H разбирает их и вызывает Instrumentation, чтобы вызвать ваши onCreate/onStart/onResume и т.д. Пара важных моментов:
- Все callback'и Activity выполняются в главном (UI) потоке, управляемом Looper.
- Если в обработчике сообщений или в Activity выполняется долгий синхронный код, очередь блокируется — возможен ANR.
- ActivityThread хранит записи об Activity (ActivityClientRecord), по которым запускает performLaunchActivity и вызывает жизненный цикл.
Пример упрощённо:
public final void handleLaunchActivity(ActivityClientRecord r) {
performLaunchActivity(r, null); // внутри вызывает onCreate, setContentView и т.д.
}
Удаляйте отложенные сообщения и callback'и H в onDestroy()/onStop(), чтобы избежать утечек через Handler.
Жизненный цикл Activity: что делать в каждом методе
Кратко: onCreate → onStart → onResume (активна); уходит в фон: onPause → onStop; при полном завершении: onDestroy; при возврате: onRestart → onStart → onResume.
Рекомендации по размещению кода:
- onCreate(): inflate UI (setContentView), инициализация ViewModel, статическая инициализация, регистрация BroadcastReceiver короткой жизни.
- onStart(): подключение подписок, start observing (LiveData), открыть соединения, но без тяжёлых задач.
- onResume(): запуск анимаций, юзер-интерактивные операции; быстрые проверки.
- onPause(): сохраняйте введённые данные, приостанавливайте анимации, отменяйте активные транзакции UI.
- onStop(): освобождайте крупные ресурсы (камера, GPS), сохраняйте состояние для восстановления.
- onDestroy(): окончательное освобождение, закрытие файлов, удаление колбеков.
- onSaveInstanceState(Bundle): сохраняйте кратковременное состояние UI (положение скролла, поля ввода).
Не держите долгие операции в onCreate/onResume — используйте корутины, Executors, WorkManager или Foreground Service для фоновых задач.
Не блокируйте UI-поток: длительные операции в callback'ах приводят к ANR и зависанию приложения.
Практические советы по отладке и оптимизации
- Логируйте lifecycle: Log.d(TAG, "onCreate"); это быстро показывает, где остановился поток.
- Удаляйте подписки и callbacks: handler.removeCallbacksAndMessages(null), unregisterReceiver().
- Используйте ViewModel для хранения состояния при пересоздании Activity (например, при повороте экрана).
- Для фоновых долгих задач применяйте WorkManager/Service, а не держите Activity в памяти.
- Включайте StrictMode в отладочных сборках, чтобы выявлять I/O и блокировки в UI-потоке.
- Тестируйте сценарии: поворот экрана, входящие звонки, переключение приложений, низкая память.
Частые ошибки
- Статические ссылки на Context/Activity → утечки памяти.
- Вложенные не-static inner-классы с долгой жизнью (Handler, Runnable) не очищаются.
- Синхронный сетевой I/O в onCreate/onResume.
- Не обрабатывается onSaveInstanceState → потеря данных при пересоздании Activity.
- Закрытие ресурсов только в onDestroy (вместо onStop) — ресурсы могут расходоваться дольше.
FAQ
-
Когда вызывать heavy init — в onCreate или фоновом потоке?
- Инициализацию UI в onCreate, тяжёлые расчёты/запросы выносите в фон (корутины/Executor/WorkManager).
-
Можно ли запускать долгую задачу в Service вместо Activity?
- Да. Для длительных задач используйте Foreground Service или WorkManager; Activity не предназначена для фоновой работы.
-
Как избежать утечек через Handler?
- Делайте Handler static или используйте WeakReference к Activity и обязательно удаляйте отложенные сообщения в onStop/onDestroy.
Освоив взаимодействие Activity и ActivityThread, вы сможете предсказуемо управлять ресурсами, избегать ANR и строить устойчивые приложения.