Sobes.tech
Middle

Kotlin loyihalarida korutinlarni qanday sozlash va foydalanish mumkin?

sobes.tech AI

AIdan javob

Korutinalarni sozlash uchun build.gradle fayliga mos keladigan bog'liqlikni qo'shish kerak.

// build.gradle (ilova moduli)
dependencies {
    //... boshqa bog'liqliklar
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // JVM, Android, JS, Native uchun
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Android uchun (agar Dispatchers.Main kerak bo'lsa)
}

Korutinalarni ishlatish quyidagilardan iborat:

  1. Hayotiy doira (Scope): Korutinalar bajariladigan va o'z hayot tsiklini boshqaradigan doira.

    • GlobalScope: Butun ilova uchun, ehtiyotkorlik bilan foydalaning, chunki xotira oqishi mumkin.
    • CoroutineScope: Aniq yaratiladi, korutinalarni bekor qilishni nazorat qilish imkonini beradi.
    • Ramkalar (masalan, lifecycleScope Android ViewModelda).
    // CoroutineScope bilan misol
    val myScope = CoroutineScope(Dispatchers.Default + SupervisorJob()) // Dispatcher va Job bilan doira yaratish
    
    fun performBackgroundTask() {
        myScope.launch { // Korutina ishga tushirish
            // Uzun hisoblash jarayoni
        }
    }
    
    fun cancelAllTasks() {
        myScope.cancel() // Doiradagi barcha korutinalarni bekor qilish
    }
    
  2. Korutinalar quruvchilari (Builders): Korutinalarni ishga tushirish uchun funksiyalar.

    • launch: Korutina ishga tushiradi, natijani aniq qaytarmaydi (Job qaytaradi).
    • async: Korutina ishga tushiradi, natijani Deferred shaklida qaytaradi.
    import kotlinx.coroutines.*
    
    suspend fun fetchData() = coroutineScope { // coroutineScope - strukturali raqobat uchun builder
        val data1 = async { networkCall1() } // async Deferred qaytaradi
        val data2 = async { networkCall2() }
    
        // ... ma'lumotlarni olishdan keyingi ishlov berish
        data1.await() // Deferred natijasini olish, korutina uxlashiga olib keladi
        data2.await()
    }
    
    suspend fun networkCall1(): String {
        delay(1000) // Tarmoq so'rovini taqlid qilish
        return "Data 1"
    }
    
    suspend fun networkCall2(): String {
        delay(1500)
        return "Data 2"
    }
    
    fun startFetching() = runBlocking { // runBlocking - joriy oqimni bloklash uchun builder
        launch { // launch Job qaytaradi
            println("Fetching data...")
            fetchData()
            println("Data fetched!")
        }
    }
    
  3. Dispetcherlar (Dispatchers): Korutinaning qaysi oqim yoki oqimlar to'plamida bajarilishini belgilaydi.

    • Dispatchers.Default: CPU intensiv vazifalar uchun.
    • Dispatchers.IO: Bloklovchi I/O operatsiyalari uchun (faylga kirish, tarmoq).
    • Dispatchers.Main: Asosiy oqim (faqat Android va Swing/JavaFX uchun).
    • Dispatchers.Unconfined: Korutina chaqiruvchining oqimida ishga tushadi, uxlashadi, va keyin ishga tushgan oqimda davom etadi.
    import kotlinx.coroutines.*
    
    fun simpleTask() {
        GlobalScope.launch(Dispatchers.IO) { // Dispatcher ko'rsatish
            // I/O operatsiyasini bajarish
            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) // Uxlash
             println("Unconfined thread 2: ${Thread.currentThread().name}") // Boshqa oqimda davom etadi (mumkin)
        }
        delay(200) // Korutinalarning tugashini kutish
    }
    
  4. To'xtatiladigan funksiyalar (Suspending functions): suspend kalit so'zi bilan belgilangan funksiyalar, ular to'xtatilishi va qayta boshlanishi mumkin, oqimni bloklamasdan. Faqat boshqa to'xtatiladigan funksiyalardan yoki korutina blokidan chaqirilishi mumkin.

  5. Bekor qilish va istisnolarni boshqarish: Korutinalar strukturali bekor qilish va istisnolarni tarqatishni qo'llab-quvvatlaydi.

    • Bekor qilish:
      import kotlinx.coroutines.*
      
      fun cancellableTask() = GlobalScope.launch {
          try {
              repeat(1000) { i ->
                  println("Working $i ...")
                  delay(100) // to'xtatilishga hurmat qiladigan suspend funksiya
              }
          } catch (e: CancellationException) {
              println("Task was cancelled!")
          } finally {
              println("Cleaning up...")
          }
      }
      
      fun main() = runBlocking {
          val job = cancellableTask()
          delay(500) // Biroz kutish
          job.cancelAndJoin() // Bekor qilish va tugashini kutish
      }
      
    • Istisnolar: launch holatida, bekor qilinmagan istisno ilovaning qulashiga olib keladi (Androidda odatda). async holatida, istisno await() chaqirilganda chiqariladi. Ko'proq nazorat uchun CoroutineExceptionHandler yoki SupervisorJob ishlatiladi.
    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val handler = CoroutineExceptionHandler { _, exception ->
            println("Caught exception: $exception")
        }
    
        val job = GlobalScope.launch(handler) { // Exception handler bilan
            throw IllegalStateException("Something went wrong")
        }
        job.join() // Tugashini kutish
    }