Sobes.tech
Middle

Kotlin layihələrində korutinləri necə qurmaq və istifadə etmək olar?

sobes.tech Süni İntellekt

AI-dan cavab

Korutinaların qurulması üçün uyğun asılılığı build.gradle faylına əlavə etmək lazımdır.

// build.gradle (tətbiq modulu)
dependencies {
    //... digər asılılıqlar
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // JVM, Android, JS, Native üçün
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Android üçün (əgər Dispatchers.Main lazımdırsa)
}

Korutinaların istifadəsi aşağıdakı kimi olur:

  1. Həyat dövrü (Scope): Korutinaların icra olunacağı sahəni və həyat dövrünü idarə etmək.

    • GlobalScope: Tətbiqin bütün həyatı üçün, ehtiyatla istifadə edin, çünki yaddaş sızmasına səbəb ola bilər.
    • CoroutineScope: Açıq şəkildə yaradılır, korutinaların ləğvini idarə etməyə imkan verir.
    • Çərçivələrdə əvvəlcədən təyin olunmuş sahələr (məsələn, lifecycleScope Android ViewModel-də).
    // CoroutineScope ilə nümunə
    val myScope = CoroutineScope(Dispatchers.Default + SupervisorJob()) // Dispatcher və Job ilə Scope yaradılması
    
    fun performBackgroundTask() {
        myScope.launch { // Korutina başlat
            // Uzun hesablama prosesi
        }
    }
    
    fun cancelAllTasks() {
        myScope.cancel() // Bütün korutinaları ləğv et
    }
    
  2. Korutina qurucuları (Builders): Korutinaları işə salmaq üçün funksiyalar.

    • launch: Korutinanı işə salır, nəticəni açıq şəkildə qaytarmır (Job).
    • async: Korutinanı işə salır, nəticəni Deferred şəklində qaytarır.
    import kotlinx.coroutines.*
    
    suspend fun fetchData() = coroutineScope { // coroutineScope - strukturli rəqabət üçün builder
        val data1 = async { networkCall1() } // async Deferred qaytarır
        val data2 = async { networkCall2() }
    
        // ... məlumatların alınmasından sonra işləmə
        data1.await() // Deferred-dən nəticəni almaq, korutinanı dincəltmək üçün çağırılır
        data2.await()
    }
    
    suspend fun networkCall1(): String {
        delay(1000) // Şəbəkə sorğusunun imitasyonu
        return "Data 1"
    }
    
    suspend fun networkCall2(): String {
        delay(1500)
        return "Data 2"
    }
    
    fun startFetching() = runBlocking { // runBlocking - cari thread-i bloklamaq üçün builder
        launch { // launch Job qaytarır
            println("Fetching data...")
            fetchData()
            println("Data fetched!")
        }
    }
    
  3. Dispatcherlər (Dispatchers): Korutinanın hansı thread və ya thread havuzunda icra olunacağını müəyyən edir.

    • Dispatchers.Default: CPU intensiv tapşırıqlar üçün.
    • Dispatchers.IO: Bloklayan I/O əməliyyatları üçün (fayl, şəbəkə).
    • Dispatchers.Main: Əsas thread (yalnız Android və Swing/JavaFX üçün).
    • Dispatchers.Unconfined: Korutinanı çağıran thread-də işə salır, dincəldikdən sonra icra edən thread-də davam edir.
    import kotlinx.coroutines.*
    
    fun simpleTask() {
        GlobalScope.launch(Dispatchers.IO) { // Dispatcher göstərilməsi
            // I/O əməliyyatını yerinə yetirmək
            println("Running on thread: ${Thread.currentThread().name}")
        }
    }
    
    fun main() = runBlocking {
        launch(Dispatchers.Default) {
            println("Default thread: ${Thread.currentThread().name}")
        }
        launch(Dispatchers.Unconfined) {
             println("Unconfined thread 1: ${Thread.currentThread().name}")
             delay(100) // Uşaq
             println("Unconfined thread 2: ${Thread.currentThread().name}") // Başqa thread-də davam edir (mümkündür)
        }
        delay(200) // Korutinaların tamamlanmasını gözləyir
    }
    
  4. Dayandırılan funksiyalar (Suspending functions): suspend açar sözü ilə işarələnmiş funksiyalar, thread-i bloklamadan dayandırıla və yenidən başlaya bilər. Yalnız digər dayandırılan funksiyalardan və ya korutina blokundan çağırıla bilər.

  5. Ləğv etmə və istisnaların idarə olunması: Korutinalar strukturlaşdırılmış ləğv etmə və istisnaların yayılmasını dəstəkləyir.

    • Ləğv etmə:
      import kotlinx.coroutines.*
      
      fun cancellableTask() = GlobalScope.launch {
          try {
              repeat(1000) { i ->
                  println("Working $i ...")
                  delay(100) // dayandırmağı hörmət edən suspend funksiya
              }
          } catch (e: CancellationException) {
              println("Task was cancelled!")
          } finally {
              println("Cleaning up...")
          }
      }
      
      fun main() = runBlocking {
          val job = cancellableTask()
          delay(500) // Bir az gözləyir
          job.cancelAndJoin() // Ləğv et və tamamlanmasını gözlə
      }
      
    • İstisnalar: launch halında, qeydə alınmamış istisna tətbiqin çökməsinə səbəb olar (Android-də standart). async halında, istisna await() çağırıldıqda atılır. Daha incə nəzarət üçün CoroutineExceptionHandler və ya SupervisorJob istifadə olunur.
    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val handler = CoroutineExceptionHandler { _, exception ->
            println("Caught exception: $exception")
        }
    
        val job = GlobalScope.launch(handler) { // Handler tətbiqi
            throw IllegalStateException("Something went wrong")
        }
        job.join() // Tamamlanmasını gözləyir
    }