Фоновая работа в Android
Главный поток приложения (его же называют UI-поток) рисует кадры и обрабатывает касания. Всё, что блокирует его дольше пяти секунд, превращается в ANR — «приложение не отвечает». Поэтому любую сетевую или файловую работу нужно уводить в фон. Но фон в Android — это не один инструмент, а целый набор с разными гарантиями: сырой поток умирает вместе с процессом, компонент Service по умолчанию сидит на главном потоке, а система в режиме экономии батареи откладывает почти всё.
Главная ловушка новичка — думать, что «фон» означает «работает всегда». На деле процесс могут убить в любой момент, а режим Doze заморозит сеть и отложит задания до окна обслуживания. Ответ зависит от требований — нужна ли работа прямо сейчас и на глазах пользователя, или это отложенная, но обязательная задача, которая должна пережить перезапуск. Полная карта — в слоях ниже.
Карта темы
- Фоновая работа и Doze — почему нельзя грузить UI-поток, чем чреват сырой
Threadи как режимDozeрежет фон. - Компонент Service — started, bound и foreground
Service, ловушка главного потока и правда проSTART_STICKY. - WorkManager — отложенная гарантированная работа, которая переживает смерть процесса, с constraints, retry и
setForeground.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Считать, что Service по умолчанию работает не в главном потоке | Долгая работа блокирует UI-поток и ловит ANR |
Грузить многоминутную задачу на сыром Thread | Процесс убьют — работа пропадёт без следа и возобновления |
Думать, что started Service освобождён от Doze | В Doze сеть и таймеры урезаны, пока не перейдёшь в foreground |
Верить, что START_STICKY переотправит исходный Intent | При перезапуске приходит null-Intent, а не ваши данные |
Считать, что WorkManager умеет только откладывать, но не выполнять сейчас | Он тянет и отложенную, и срочную (expedited) работу, а long-running — через foreground |
| Забыть постоянное уведомление у foreground-задачи | Система не даст задаче статус foreground — её быстро прибьют |
Значение для собеседований
Тему спрашивают, чтобы проверить, отличаете ли вы механизмы фонового выполнения по их гарантиям, а не по названию. Кандидат, который говорит «сырой Thread не переживает смерть процесса, поэтому для гарантированной работы беру WorkManager, а для видимой сейчас — foreground Service», сразу опережает «ну, запущу в фоне».
Что обычно проверяют:
- Почему нельзя блокировать UI-поток и что такое ANR.
- Что
Serviceпо умолчанию живёт на главном потоке и работу надо уводить самому. - Как
Dozeограничивает фон и почему foreground обходит эти ограничения. - Когда брать
WorkManager, а когда foregroundService, и что станет с задачей при убийстве процесса.
Типичный неверный ответ: «Service сам создаёт фоновый поток, а START_STICKY восстановит задачу с данными». На деле Service работает на главном потоке, а START_STICKY перезапускает компонент с null-Intent — восстановление состояния пишете вы сами.