Ответ
В Android рекомендуется использовать разные CoroutineScope для разных жизненных циклов компонентов (Activity, ViewModel и т.д.), чтобы избежать утечек памяти и корректно управлять отменой корутин.
- Activity/Fragment Scope:
lifecycleScopeавтоматически отменяет корутины при уничтожении компонента. - ViewModel Scope:
viewModelScopeотменяет корутины при очистке ViewModel. - Global Scope:
GlobalScopeживет всё время работы приложения и может привести к утечкам, если не управлять им вручную.
Пример с viewModelScope:
class MyViewModel : ViewModel() {
fun fetchData() {
viewModelScope.launch {
// Работа с данными
}
}
}
Использование разных скоупов делает код безопасным и предсказуемым.
Ответ 18+ 🔞
Слушай, а вот эта вся история с корутинами в Android — это просто ёперный театр, если не разобраться. Представь: ты пишешь приложение, а оно потом память жрёт, как не в себя, и в итоге накрывается медным тазом. А всё почему? Потому что чуваки не понимают, какой CoroutineScope куда пихать.
Вот смотри, тут всё просто, как три копейки. Для каждой штуки в андроиде — свой скоуп, свой карман, куда ты эти асинхронные задачи складываешь. И главное — чтобы этот карман вовремя вытряхнули, когда он уже не нужен.
- Для Activity или Fragment — бери
lifecycleScope. Это гениально, ёпта. Создал активность — есть скоуп. Закрыл активность, пользователь ушёл —lifecycleScopeберёт и отменяет ВСЕ корутины, которые в нём запущены. Автоматом! Никаких утечек памяти, потому что твоя корутина не будет впустую шаманить с уже мёртвым интерфейсом. Чистая магия, ядрёна вошь. - Для ViewModel — тут свой царь,
viewModelScope. ViewModel же может пережить поворот экрана, да? Вот и её скоуп живёт ровно столько, сколько живет сама вьюмодель. Когда её почистят, все корутины — хоба! — отменятся. Красота.
Вот, смотри, как это выглядит в коде, простой пример:
class MyViewModel : ViewModel() {
fun fetchData() {
viewModelScope.launch {
// Тут твоя работа с данными, запросы в сеть, всё дела
}
}
}
Запустил метод — корутина поехала в viewModelScope. Пользователь ушёл с экрана, ViewModel очистилась — и твоя фоновая работа тоже остановилась. Ничего никуда не убежало, доверия ебать ноль, но всё предсказуемо.
А теперь главный антигерой — GlobalScope. Вот это, бля, чистой воды распиздяйство, если использовать его в компонентах. Он же живёт ВСЮ жизнь приложения! Ты в активити запустил через него задачу, активити умерла, а корутина себе летит дальше, как хуй с горы, и держит ссылку на всё, что успела захватить. Память течёт, приложение тормозит, потом получаешь креш — и волнение ебать, где искать причину.
Короче, мораль проще пареной репы: не выёбывайся, используй правильные скоупы. lifecycleScope для всего, что связано с экраном, и viewModelScope для бизнес-логики. А GlobalScope оставь для каких-нибудь глобальных сервисов, которые реально должны работать всегда. Тогда и память будет цела, и логика отмены прозрачна. Всё гениальное — просто, как да похуй.