С какими проблемами сталкивались при работе с потоками
Что проверяют
Понимаете ли вы, почему главный поток нельзя занимать, и на чём сегодня пишут фон. Ответ про AsyncTask без оговорок сразу показывает возраст опыта: ждут корутин, структурной конкурентности и понимания, что гонка живёт в данных, а не в потоках.
Как отвечать
Расскажите про реальный случай и по дороге назовите узлы:
- главный поток. Диск и сеть на нём это подвисания и ANR, а обновлять интерфейс можно только оттуда;
- инструменты.
viewModelScopeиlifecycleScopeпривязывают работу к жизненному циклу,Dispatchers.IOдля блокирующих вызовов,Dispatchers.Defaultдля расчётов, работа, переживающая процесс, уходит вWorkManager; - отмена. Корутина отменяется только кооперативно: цикл без точек приостановки и без проверки активности продолжит крутиться после закрытия экрана;
- общее состояние. Две корутины пишут в одну переменную, и вы получаете плавающий баг. Помогают
Mutex, атомарные типы или атомарное обновлениеStateFlow, но неsynchronized, который просто блокирует поток пула; - подписки. Сбор потока данных оборачивается в
repeatOnLifecycle, иначе невидимый экран продолжает получать обновления и держать ссылки.
Где спотыкаются
Считают Dispatchers.IO волшебным. Он не превращает блокирующий вызов в неблокирующий, а просто отдаёт ему поток из пула, и сотня одновременных блокирующих вызовов этот пул выест.
Второе: ловят исключение через try вокруг launch. Туда оно не придёт: обрабатывать нужно внутри корутины или через обработчик в контексте. Отдельно помните, что отмена тоже приходит исключением, и глотать его общим catch нельзя.
Третье: думают, что переезд на корутины убирает гонки. Гонка возникает из-за разделяемого изменяемого состояния, и сменой библиотеки она не лечится: лечится она владением данными, когда пишет одно место, а остальные читают снимок.