CoroutineScope — bu korutinaning hayot doirasini belgilaydigan va yangi korutinalarni ishga tushirish uchun kontekstni ta’minlaydigan Kotlin interfeysidir. Kotlin hujjatlariga, 2025 ko’ra, har bir CoroutineScope nusxasi CoroutineContext ni o’z ichiga oladi va unda ishga tushirilgan barcha korutinalarni boshqaradi. Scope tugaganda (cancel), barcha qaram korutinalar avtomatik ravishda bekor qilinadi, bu esa xotira oqishining oldini oladi.
Asosiy ma’lumotlar
CoroutineScope — bu kotlinx.coroutines kutubxonasidagi korutinalar uchun konteyner bo’lib xizmat qiladigan fundamental interfeysdir. U korutinalarning hayot chegaralarini belgilaydi: scope tugaganda, uning ichidagi barcha korutinalar avtomatik ravishda bekor qilinadi.
public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
Interfeys faqat bitta maydonni o’z ichiga oladi — coroutineContext. U orqali scope unda ishga tushirilgan barcha korutinalar uchun dispetcher (Dispatcher), topshiriq (Job), istisnolarni boshqarish va kontekstning boshqa elementlarini ta’minlaydi.
Barcha korutina ishga tushirish funksiyalari — launch, async, runBlocking — CoroutineScope ga kengaytma funksiyalardir. Bu shuni anglatadiki, ularni faqat scope ob’ekti mavjud bo’lganda chaqirish mumkin. Bunday dizayn har bir korutinaning aniq belgilangan ota-onasi va hayotiy siklga ega bo’lishini kafolatlaydi.
Android-da har bir arxitektura komponenti o’z scope-iga ega: ViewModel uchun viewModelScope, Activity/Fragment uchun lifecycleScope. Server ilovalarida scope HTTP so’rovi yoki ma’lumotlar bazasi bilan bog’lanishlar hovuziga bog’lanishi mumkin.
CoroutineScope ning ichki tuzilishini tushunish Job tushunchasi va strukturaviy raqobat prinsipi bilan tanishishni talab qiladi.
Har bir korutina ishga tushirilganda Job ob’ektini qaytaradi (yoki async uchun Deferred). Job aniq hayotiy siklga ega bo’lgan topshiriqni ifodalaydi: New, Active, Completing, Completed, Cancelling, Cancelled. Job ob’ektlari daraxtsimon tuzilma hosil qiladi:
Strukturaviy raqobat — Kotlin Coroutines ning asosiy arxitektura prinsipi bo’lib, korutinaning umr ko’rish muddati uning scope-ining umr ko’rish muddatiga bog’langan. Bu „fire-and-forget” modelidan farq qiladi, bu erda korutina scope tugaganidan keyin ham yashashda davom etadi. Strukturaviy raqobatning afzalliklari:
scope.cancel() chaqirilganda, Job scope Cancelled holatiga o’tadi, bu esa barcha qaram Job-larni rekursiv ravishda bekor qiladi. Bekor qilinganidan keyin scope faqat yangi CoroutineScope nusxasini yaratish orqali qayta ishlatilishi mumkin.
CoroutineScope fabrika funksiyasi orqali yoki sinfda interfeysni amalga oshirish orqali yaratilishi mumkin. Ikkala yondashuvni ko’rib chiqamiz.
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
scope.launch {
println("${Thread.currentThread().name} da ishlaydi")
}
Fabrika funksiyasi CoroutineContext ni qabul qiladi va belgilangan kontekst bilan scope yaratadi. Misolda CPU intensiv topshiriqlar uchun Dispatchers.Default va qaram korutinalar orasidagi istisnolarni izolyatsiya qiluvchi SupervisorJob ishlatilgan.
class MyRepository {
private val scope = CoroutineScope(Dispatchers.IO + Job())
suspend fun fetchData(): Data = scope.async {
api.getData()
}.await()
fun cleanup() {
scope.cancel()
}
}
Scope-ni sinf maydoni sifatida saqlaymiz va uni bekor qilish uchun qo’lda cleanup ni chaqiramiz. Bu boshqariladigan hayotiy siklli komponentlar — masalan, repozitoriylar yoki menejerlar uchun mos keladi.
Kotlin by kalit so’91 orqali CoroutineScope amalga oshirilishini delegatsiya qilishga imkon beradi:
class DataLoader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun load() {
launch {
// korutina DataLoader scope-da ishlaydi
}
}
}
Bunday yondashuv sinfning o’zi scope bo’lganda va korutina ishga tushirish usullarini taqdim etmoqchi bo’lganda qulay. Biroq ehtiyot bo’ling: sinf CoroutineScope ning barcha usullarini, jumladan cancel ni meros qilib oladi, bu esa inkapsulyatsiyani buzishi mumkin.
GlobalScope — butun ilova uchun CoroutineScope singletonidir. Uni ishlab chiqarish kodida ishlatish rasman tavsiya etilmaydi.
JetBrains GlobalScope ni faqat kamdan-kam stsenariylarda ruxsat beradi: barcha Activity-lar yopilgandan keyin ham yashashi kerak bo’lgan ilova darajasidagi fon jarayonlari (masalan, ma’lumotlarni sinxronlash, analitika). Ammo bu hollarda ham CoroutineScope(SupervisorJob()) bilan o’z scope-ingizni yaratish afzalroqdir.
Har doim aniq hayotiy sikl boshqaruvi bilan moslashtirilgan CoroutineScope-dan foydalaning. Android-da bu viewModelScope va lifecycleScope. Server ilovalarida har bir so’rov yoki ulanish hovuzi uchun scope yarating.
Ikkala funksiya ham parallel topshiriqlar uchun vaqtinchalik scope yaratadigan suspend funksiyalardir, ammo ularning istisnolar paytidagi xatti-harakati tubdan farq qiladi.
| Xususiyat | coroutineScope | supervisorScope |
|---|---|---|
| Xato paytidagi xatti-harakat | Qaram korutinadagi istisno qolganlarini bekor qiladi | Qaram korutinadagi istisno qolganlarini bekor qilmaydi |
| Xatoning tarqalishi | Ha, birinchi istisno tashqariga tarqaladi | Ha, birinchi istisno tashqariga tarqaladi |
| Standart Job | Job() — qaram korutinalar ota-onaga bog’langan | SupervisorJob() — qaram korutinalar bir-biriga bog’liq emas |
| Odatiy foydalanish holati | Bir necha bosqichdan iborat atom operatsiya | Mustaqil parallel topshiriqlar (UI yuklashlar) |
coroutineScope-dan bir nechta parallel operatsiyalar yagona atom operatsiyani tashkil qilganda foydalaning. Masalan, uchta serverdan ma’lumotlarni yuklash: agar bitta so’rov muvaffaqiyatsiz bo’lsa, qolganlari ma’nosizdir.
suspend fun loadProductPage(): ProductPage = coroutineScope {
val product = async { api.getProduct() }
val reviews = async { api.getReviews() }
ProductPage(product.await(), reviews.await())
}
Agar getProduct yoki getReviews istisno tashlasa — ikkala korutina bekor qilinadi va istisno chaqiruvchi kodga tarqaladi.
supervisorScope-dan parallel operatsiyalar bir-biriga bog’liq bo’lmaganda foydalaning. Masalan, bir nechta mustaqil bo’limlarda profil ma’lumotlarini yuklash: agar tavsiyalar bo’limi muvaffaqiyatsiz bo’lsa, profil sarlavhasi va do’stlar ro’yxati ko’rsatilishi kerak.
Kotlin-da CoroutineScope dan foydalanishda dasturchilarning eng keng tarqalgan xatolarini ko’rib chiqamiz.
Korutina oqishining eng keng tarqalgan stsenariysi — komponent tugaganda cancel chaqirmasdan scope yaratish. Agar scope bekor qilinmasa, korutinalar ob’ektlarga havolalarni ushlab, ishlashda davom etadi. Android-da avtomatik bekor qilinadigan viewModelScope yoki lifecycleScope-dan foydalaning.
GlobalScope Android komponentlarining hayotiy siklini e’tiborsiz qoldiradi. Activity yopilgandan keyin GlobalScope-da ishga tushirilgan korutina ishlashda davom etadi va UI-ni yangilashga harakat qiladi — bu crash-ga olib keladi. UI komponentlari uchun har doim lifecycleScope-dan foydalaning.
cancel() chaqirilgandan keyin scope-ni qayta ishlatib bo’lmaydi — undagi barcha korutinalar allaqachon tugallangan. Fabrika funksiyasi orqali yangi CoroutineScope nusxasini yarating. Job() qayta faollashtirishni qo’llab-quvvatlamaydi.
by orqali delegatsiya qilishda sinf istalgan joydan chaqirilishi mumkin bo’lgan ommaviy cancel() usulini oladi, bu inkapsulyatsiyani buzadi. Scope-ni xususiy maydon sifatida saqlang, interfeysni delegatsiya qilmang.
Tez-tez so’raladigan savollar
CoroutineScope — CoroutineContext-ga ega bo’lgan va korutinalarning hayotiy sikli uchun mas’ul bo’lgan interfeys. CoroutineContext — korutina “qanday” bajarilishini belgilaydigan elementlar to’plami (dispetcher, job, xato boshqaruvi). Farqlardan biri: scope korutinalarni yaratadi, context ularning xatti-harakatini boshqaradi.
Ha, bu standart na’sh: CoroutineScope(Dispatchers.IO + SupervisorJob()). SupervisorJob ulardan birida istisno bo’lganda qaram korutinalarning kaskadli bekor qilinishining oldini oladi. Bu biridagi xato boshqalarni to’xtatmasligi kerak bo’lgan mustaqil parallel topshiriqlar uchun foydalidir.
Scope-dagi korutinalar soni bo’yicha cheklovlar yo’q — ular faqat mavjud xotira va dispetcher sozlamalari bilan cheklangan. Amaliy chegara odatda bitta scope-da minglab faol korutinalar ni tashkil qiladi. Biroq, ko’p sonli korutinalar arxitektura muammolariga ishora qilishi mumkin.
To’g’ri usul — scope-ni konstruktor orqali sinfga uzatish yoki kotlinx-coroutines-test dan runBlockingTest / runTest dan foydalanish. Sinovlarda scope-ni TestCoroutineDispatcher bilan almashtirish va korutinalarning bajarilishini qo’lda boshqarish mumkin.
Yo’q, scope korutina uchun tashqi konteynerdir. Korutinaning o’zi scope emas. Biroq, korutina ichida qaram korutinalarni parallel ishga tushirish uchun coroutineScope yoki supervisorScope orqali yangi scope yaratish mumkin.
Xulosa
Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz
IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.