CoroutineScope — Kotlin interfeysidir, korutinin həyat müddətini müyyənləşdirir və yeni korutinlər başlatmaq üçün kontekst təmin edir. Kotlin sənədləşdirməsinə, 2025 görə, hər bir CoroutineScope nüsxəsi CoroutineContext saxlayır və orada başladılmış bütün korutinləri idarə edir. Scope başa çatdıqda (cancel), bütün alt korutinlər avtomatik ləğv edilir ki, bu da yaddaş sızıntılarının qarşısını alır.
Əsas məqamlar
CoroutineScope — kotlinx.coroutines kitabxanasından korutinlər üçün konteyner rolunu oynayan fundamental interfeysdir. O, korutinlərin həyat sərhəddlərini müyyənləşdirir: scope başa çatdıqda, onun daxilindəki bütün korutinlər avtomatik ləğv edilir.
public interface CoroutineScope {
public val coroutineContext: CoroutineContext
}
Interfeys yalnız bir sahə ehtiva edir — coroutineContext. Onun vasitəsilə scope daxilində başıdılmış bütün korutinlər üçün dispetçer (Dispatcher), tapşırıq (Job), istisna idarəetməsi və kontekstin digər elementlərini təmin edir.
Bütün korutin başlatma funksiyaları — launch, async, runBlocking — CoroutineScope üzərində genişləndirmə funksiyalarıdır. Bu o deməkdir ki, onları yalnız scope obyekti olduqda çağırmaq olar. Belə bir dizayn hər bir korutinin aşkar müəyyənləşmiş valideyn və həyat dövrünə malik olmasını təmin edir.
Android-də hər bir memarlıq komponentinin öz scope-u var: ViewModel üçün viewModelScope, Activity/Fragment üçün lifecycleScope. Server tətbiqlərində scope HTTP sorğusuna və ya verilənlər bazası ilə əlaqə hovuzuna bağlana bilər.
CoroutineScope-un daxili quruluşunu başa düşmək Job konsepsiyası və struktur rəqabət prinsipi ilə tanışlıq tələb edir.
Hər bir korutin başıdıldıqdan sonra Job obyekti qaytarır (və ya async üçün Deferred). Job müəyyən həyat dövrü olan bir tapşırığı təmsil edir: New, Active, Completing, Completed, Cancelling, Cancelled. Job obyektləri ağacşəkilli struktur yaradır:
Struktur rəqabət — Kotlin Coroutines-in əsas memarlıq prinsipi olub, korutinin həyat müddətinin onun scope-un həyat müddətinə bağlı olduğunu bildirir. Bu, korutinin scope başa çatdıqdan sonra da yaşamağa davam etdiyi „fire-and-forget” modelindən fərqlənir. Struktur rəqabətin üstünlükləri:
scope.cancel() çağırıldıqda, Job scope Cancelled vəziyyətinə keçir və bu, bütün alt Job-ları rekursiv şəkildə ləğv edir. Ləğv edildikdən sonra scope yalnız yeni CoroutineScope nüsxəsi yaradılmaqla təkrar istifadə edilə bilər.
CoroutineScope fabrik funksiyası və ya sinifdə interfeysin tətbiqi ilə yaradıla bilər. Hər iki yanaşmanı nəzərdən keçirək.
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
scope.launch {
println("${Thread.currentThread().name} üzərində işləyir")
}
Fabrik funksiyası CoroutineContext qəbul edir və göstərilən kontekstlə scope yaradır. Nümunədə CPU intensiv tapşırıqlar üçün Dispatchers.Default və alt korutinlər arasında istisnaları təcrid edən SupervisorJob istifadə olunur.
class MyRepository {
private val scope = CoroutineScope(Dispatchers.IO + Job())
suspend fun fetchData(): Data = scope.async {
api.getData()
}.await()
fun cleanup() {
scope.cancel()
}
}
Scope-u sinif sahəsi kimi saxlayır və onu ləğv etmək üçün əl ilə cleanup çağırırıq. Bu, idarə olunan həyat dövrü olan komponentlər — məsələn, repozitoriyalar və ya menecerlər üçün uyğundur.
Kotlin by açar sözü vasitəsilə CoroutineScope tətbiqini deleqasiya etməyə imkan verir:
class DataLoader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
fun load() {
launch {
// korutin DataLoader scope-da işləyir
}
}
}
Bu yanaşma sinfin özü scope olduqda və korutin başlatma metodlarını təmin etmək istədikdə rahatdır. Bununla belə, ehtiyatlı olmaq lazımdır: sinif CoroutineScope-un bütün metodlarını, o cümlədən cancel-i miras alır ki, bu da inkapsulyasiyanı poza bilər.
GlobalScope — bütün tətbiq üçün CoroutineScope sinqletonudur. Onun istehsalat kodunda istifadəsi rəsmi olaraq tövsiyə edilmir.
JetBrains GlobalScope-u yalnız nadir ssenarilərdə icazə verir: bütün Activity-lər bağlandıqdan sonra da işləməli olan tətbiq səviyyəli fon prosesləri (məsələn, verilənlərin sinxronizasiyası, analitika). Lakin bu hallarda belə CoroutineScope(SupervisorJob()) ilə öz scope-unu yaratmaq daha üstün tutulur.
Həmişə fərqləşdirilmiş CoroutineScope-dan aşkar həyat dövrü idarəetməsi ilə istifadə edin. Android-də bunlar viewModelScope və lifecycleScope-dur. Server tətbiqlərində hər sorğu və ya əlaqə hovuzu üçün scope yaradın.
Hər iki funksiya paralel tapşırıqlar üçün müvəqqəti scope yaradan suspend funksiyalardır, lakin onların istisnalar zamanı davranışı prinsipial olaraq fərqlənir.
| Xarakteristika | coroutineScope | supervisorScope |
|---|---|---|
| Səhv zamanı davranış | Alt korutindəki istisna bütün digərlərini ləğv edir | Alt korutindəki istisna digərlərini ləğv etmir |
| Səhvin yayılması | Bəli, ilk istisna xaricə yayılır | Bəli, ilk istisna xaricə yayılır |
| Defolt Job | Job() — alt korutinlər valideynə bağlıdır | SupervisorJob() — alt korutinlər bir-birindən asılı deyil |
| Tipik istifadə halı | Bir neçə addımdan ibarət atom əməliyyat | Müstəqil paralel tapşırıqlar (UI yükləmələri) |
coroutineScope-dan bir neçə paralel əməliyyat vahid atom əməliyyat təşkil etdikdə istifadə edin. Məsələn, üç serverdən verilənlərin yüklənməsi: bir sorğu uğursuz olarsa, qalanların mənası yoxdur.
suspend fun loadProductPage(): ProductPage = coroutineScope {
val product = async { api.getProduct() }
val reviews = async { api.getReviews() }
ProductPage(product.await(), reviews.await())
}
getProduct və ya getReviews istisna atarsa — hər iki korutin ləğv edilir və istisna çağıran koda yayılır.
supervisorScope-dan paralel əməliyyatlar bir-birindən asılı olmadıqda istifadə edin. Məsələn, bir neçə müstəqil bölmədə profil məlumatlarının yüklənməsi: tövsiyələr bölməsi uğursuz olarsa, profil başlığı və dost siyahısı göstərilməlidir.
Kotlin-də CoroutineScope istifadə edərkən proqramçıların ən çox yol verdiyi səhvləri nəzərdən keçirək.
Korutin sızıntısının ən geniş yayılmış ssenarisi — komponent başa çatdıqda cancel çağırmadan scope yaratmaqdır. Scope ləğv edilməzsə, korutinlər obyektlərə istinadları saxlayaraq işləməyə davam edir. Android-də avtomatik ləğv edilən viewModelScope və ya lifecycleScope-dan istifadə edin.
GlobalScope Android komponentlərinin həyat dövrünə məhəl qoymur. Activity bağlandıqdan sonra GlobalScope-da başıdılmış korutin yenə də işləməyə və UI-nı yeniləməyə çalışacaq — bu da crash-a səbəb olacaq. UI komponentləri üçün həmişə lifecycleScope istifadə edin.
cancel() çağırıldıqdan sonra scope təkrar istifadə edilə bilməz — onun daxilindəki bütün korutinlər artıq tamamlanmışdır. Fabrik funksiyası vasitəsilə yeni CoroutineScope nüsxəsi yaradın. Job() təkrar aktivləşdirməni dəstəkləmir.
by vasitəsilə deleqasiya zamanı sinif istənilən yerdən çağırıla bilən ictimai cancel() metodu alır ki, bu da inkapsulyasiyanı pozur. Scope-u şəxsi sahə kimi saxlayın, interfeysi deleqasiya etməyin.
Tez-tez verilən suallar
CoroutineScope — CoroutineContext-ə sahib olan və korutinlərin həyat dövrünə cavabdeh olan interfeysdir. CoroutineContext — korutinin “necə” yerinə yetirildiyini müyyənləşdirən elementlər toplusudur (dispetçer, job, səhv idarəetməsi). Fərqlərdən biri: scope korutinləri yaradır, context onların davranışını idarə edir.
Bəli, bu standart nümunədir: CoroutineScope(Dispatchers.IO + SupervisorJob()). SupervisorJob alt korutinlərdən birində istisna olduqda kaskad ləğv edilməsinin qarşısını alır. Bu, birindəki səhvin digərlərini dayandırmaması lazım olan müstəqil paralel tapşırıqlar üçün faydalıdır.
Scope-da korutinlərin sayı ilə bağlı məhdudiyyət yoxdur — onlar yalnız mövcud yaddaş və dispetçer parametrləri ilə məhdudlaşır. Praktiki hədd adətən bir scope-da minlərlə aktiv korutin təşkil edir. Bununla belə, çox sayda korutin memarlıq problemlərinə işərə edə bilər.
Düzgün üsul scope-u konstruktor vasitəsilə sinfə ötürmək və ya kotlinx-coroutines-test-dən runBlockingTest / runTest istifadə etməkdir. Testlərdə scope-u TestCoroutineDispatcher ilə əvəz edə və korutinlərin icrasını əl ilə idarə edə bilərsiniz.
Xeyr, scope korutin üçün xarici konteynerdir. Korutinin özü scope deyil. Bununla belə, korutin daxilində alt korutinləri paralel başlatmaq üçün coroutineScope və ya supervisorScope vasitəsilə yeni scope yaradıla bilər.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun