Android жёстко ограничивает работу в фоне ради батареи. На собесе проверяют, понимаете ли вы главный поток и ANR, корутины в Android, сервисы и их ограничения, и когда брать WorkManager.
Главный поток и ANR
Главный (UI) поток обрабатывает ввод, рисует кадры и вызывает колбэки жизненного цикла. Кадр при 60 Гц должен уложиться в 16 мс, при 120 Гц в 8 мс. Долгая работа на главном потоке даёт рывки (jank), а если приложение не отвечает на ввод 5 секунд, система показывает диалог ANR (Application Not Responding). Для BroadcastReceiver.onReceive лимит около 10 секунд в foreground.
Нельзя на главном потоке: сеть (будет NetworkOnMainThreadException), диск, база, тяжёлые вычисления, декодирование больших картинок.
Под капотом главный поток это Looper с MessageQueue: Handler.post кладёт задачу в очередь, Dispatchers.Main в корутинах работает поверх него.
Корутины в Android
viewModelScopeдля работы экрана,lifecycleScopeдля UI-задач Activity/Fragment.Dispatchers.IOдля блокирующего ввода-вывода,Defaultдля вычислений. Suspend-функции репозиториев main-safe: сами переключают диспетчер черезwithContext.- Корутина в
viewModelScopeотменится при закрытии экрана. Работа, которая должна завершиться независимо от экрана (отправка сообщения, синхронизация), нужна в другом месте: в application-scope (если процесс жив) или в WorkManager (если должна пережить смерть процесса).
Устаревшие подходы, которые встречаются в легаси: AsyncTask (deprecated, утечки и проблемы при повороте), голые Thread, Executor + Handler, RxJava (живёт во многих проектах).
Сервисы
Service это компонент без UI. Виды:
- Started service: запущен
startService, работает доstopSelf. С Android 8 (API 26) фоновые started-сервисы ограничены: приложение в фоне не может их запускать (IllegalStateException). - Foreground service: показывает постоянное уведомление, пользователь знает о работе. Запуск
startForegroundServiceи обязательный вызовstartForegroundв течение нескольких секунд. С Android 14 (API 34) обязателен тип foreground-сервиса (dataSync,mediaPlayback,location,camera,shortServiceи др.) в манифесте и при запуске, с соответствующим разрешением. С Android 12 запуск foreground-сервиса из фона запрещён, кроме исключений. - Bound service: клиенты привязываются через
bindServiceи общаются черезIBinder, живёт, пока есть привязки.
Сервис по умолчанию выполняется на главном потоке: внутри всё равно нужны корутины или потоки.
WorkManager
Рекомендованное API для отложенной гарантированной работы: она выполнится, даже если приложение закрыли или устройство перезагрузилось.
class SyncWorker(ctx: Context, params: WorkerParameters) : CoroutineWorker(ctx, params) {
override suspend fun doWork(): Result = try {
repository.sync()
Result.success()
} catch (e: IOException) {
if (runAttemptCount < 5) Result.retry() else Result.failure()
}
}
val request = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(Constraints(requiredNetworkType = NetworkType.CONNECTED))
.setBackoffCriteria(BackoffPolicy.EXPONENTIAL, 30, TimeUnit.SECONDS)
.build()
WorkManager.getInstance(context)
.enqueueUniqueWork("sync", ExistingWorkPolicy.KEEP, request)
- Ограничения: сеть, зарядка, не низкий заряд, свободное место, простой устройства.
PeriodicWorkRequestс минимальным интервалом 15 минут.- Уникальная работа (
enqueueUniqueWork) защищает от дублей. - Цепочки
beginWith(a).then(b), входные и выходные данныеData(маленькие, до 10 КБ). - Срочная работа:
setExpedited(...). Долгая работа с уведомлением:setForeground()внутри воркера. - Наблюдение за статусом:
getWorkInfoByIdFlow. - Хранит задачи в своей базе, под капотом использует JobScheduler.
Чего WorkManager не гарантирует: точное время запуска. Система откладывает работу из-за Doze и App Standby Buckets. Для точного будильника есть AlarmManager.setExactAndAllowWhileIdle (с Android 12 нужен доступ к точным будильникам, а с Android 14 разрешение SCHEDULE_EXACT_ALARM по умолчанию не выдаётся большинству новых приложений).
Как выбрать
| Задача | Инструмент |
|---|---|
| Работа, пока пользователь на экране | корутины в viewModelScope |
| Должно завершиться, даже если экран закрыли, но процесс жив | application-scope |
| Гарантированно выполнить, можно отложить (синхронизация, загрузка логов) | WorkManager |
| Долгая работа, о которой знает пользователь (музыка, навигация, загрузка файла) | foreground service с нужным типом или WorkManager с setForeground |
| В точное время | AlarmManager |
Частые ошибки
- Сеть или база на главном потоке.
- Работа, которая должна завершиться, в
viewModelScope. Thread.sleepи блокирующие вызовы вDispatchers.Main.- Foreground service без типа на Android 14+.
PeriodicWorkRequestс ожиданием интервала меньше 15 минут.enqueueсинхронизации при каждом старте без уникального имени: дубли.
Что спросят на собесе
- Что такое ANR и как его избежать?
- Как работает главный поток, Looper и Handler?
- Какие бывают сервисы и какие ограничения появились в новых Android?
- Когда WorkManager, а когда foreground service?
- Как WorkManager гарантирует выполнение и что такое constraints?