Можно ли выполнять сетевые запросы в главном потоке
Что проверяют
Знаете ли вы, что это не просто «плохая практика», а запрет, который система проверяет сама. Следом спрашивают, какой инструмент вы выберете для запроса с экрана, а какой для работы, которая должна пережить закрытие приложения.
Как отвечать
Нельзя. Начиная с Android 3.0 (API 11) система бросает NetworkOnMainThreadException при попытке сетевого вызова в главном потоке. Причина понятна: главный поток рисует кадры, на 60 Гц на кадр отводится около 16 мс, а сетевой запрос длится сотни миллисекунд. Если поток не отвечает на ввод 5 секунд, система показывает диалог ANR, и пользователь может просто закрыть приложение.
Каркас современного ответа:
- корутины:
viewModelScope.launch { ... }в ViewModel, а сам запрос уходит наDispatchers.IOчерезwithContext. Работа отменяется вместе с ViewModel; - Retrofit:
suspend-методы интерфейса безопасно вызывать из главного потока, Retrofit сам выполняет запрос в фоне, лишнийwithContextне нужен; - OkHttp:
enqueue()с колбэком, если корутин в проекте нет; - WorkManager: не для данных экрана, а для отложенной гарантированной работы, например выгрузки файла или синхронизации, которая должна выполниться даже после перезагрузки устройства.
AsyncTask упомяните только как историю: он объявлен устаревшим в API 30 и в новом коде не используется. Для диагностики в debug-сборке включают StrictMode с detectNetwork() и detectDiskReads(), тогда блокирующие вызовы всплывают ещё до релиза.
Где спотыкаются
Выносят запрос в Thread и оттуда же меняют TextView. Получают CalledFromWrongThreadException: трогать View можно только из главного потока.
Используют runBlocking в Activity или ViewModel. Код выглядит как корутинный, но главный поток всё равно стоит и ждёт ответа сети.
«Чинят» исключение через StrictMode.setThreadPolicy(ThreadPolicy.Builder().permitAll().build()). Исключение пропадает, зависания и ANR остаются.