Sobes.tech
Middle

Kotlin долбоорлорунда корутиндерди кантип орнотуу жана колдонуу керек?

sobes.tech AI

AIден жооп

Корутина конфигурациялоо үчүн build.gradle файлына тиешелүү көзкаранды болууларды кошуу керек:

// build.gradle (программа бөлүмү)
dependencies {
    //... башка көзкаранды болуулар
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // JVM, Android, JS, Native үчүн
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") // Android үчүн (эгер Dispatchers.Main керек болсо)
}

Корутина колдонуу төмөнкүдөй:

  1. Өмүр чөйрө (Scope): Корутина кайсы жерде ишке ашарын жана анын өмүр циклин башкаруу:

    • GlobalScope: Бардык колдонмо үчүн, сак болуу керек, анткени эс тутумду агызуу коркунучу бар.
    • CoroutineScope: Ачык түрдө түзүлөт, корутиналарды токтотууга мүмкүндүк берет.
    • Фреймворктардын алдын ала аныкталган чөйрөлөрү (мисалы, Android ViewModelдеги lifecycleScope).
    // CoroutineScope менен мисал
    val myScope = CoroutineScope(Dispatchers.Default + SupervisorJob()) // Dispatcher жана Job менен чөйрө түзүү
    
    fun performBackgroundTask() {
        myScope.launch { // Корутина ишке киргизүү
            // Узак иштөөчү эсептөө процесси
        }
    }
    
    fun cancelAllTasks() {
        myScope.cancel() // Бардык корутиналарды токтотуу
    }
    
  2. Корутина түзүүчүлөр (Builders): Корутина баштоо үчүн функциялар:

    • launch: Корутина баштайт, ал жыйынтыкты так көрсөтпөйт (кайтаруу Job).
    • async: Корутина баштайт, ал натыйжаны Deferred түрүндө кайтарат:
    import kotlinx.coroutines.*
    
    suspend fun fetchData() = coroutineScope { // coroutineScope - структураланган атаандаштык үчүн
        val data1 = async { networkCall1() } // async Deferred кайтарат
        val data2 = async { networkCall2() }
    
        // ... алынган маалыматтарды иштетүү
        data1.await() // Deferred натыйжасын алуу, корутинаны токтотот күтүп
        data2.await()
    }
    
    suspend fun networkCall1(): String {
        delay(1000) // Тармактык суроо-талапты имитациялоо
        return "Data 1"
    }
    
    suspend fun networkCall2(): String {
        delay(1500)
        return "Data 2"
    }
    
    fun startFetching() = runBlocking { // runBlocking - учурдагы агымды блокдоо
        launch { // launch кайтарат `Job`
            println("Fetching data...")
            fetchData()
            println("Data fetched!")
        }
    }
    
  3. Диспетчерлер (Dispatchers): Корутина кайсы агымда же агымдар тобунда ишке ашарын аныктайт:

    • Dispatchers.Default: CPU-интенсивдүү иштер үчүн
    • Dispatchers.IO: блоктоочу I/O операциялары үчүн
    • Dispatchers.Main: негизги агым (тек гана Android жана Swing/JavaFX)
    • Dispatchers.Unconfined: Корутина чакырган агымда башталат, кийин башка агымда уланат:
    import kotlinx.coroutines.*
    
    fun simpleTask() {
        GlobalScope.launch(Dispatchers.IO) { // Диспетчер көрсөтүү
            // I/O операциясын аткаруу
            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) // Усыпка
             println("Unconfined thread 2: ${Thread.currentThread().name}") // Башталгандан кийин башка агымда уланат
        }
        delay(200) // Корутина аякташын күтүү
    }
    
  4. Туташтырылган функциялар (Suspending functions): suspend деп белгиленген функциялар, алар токтоп, кайра улантылат, агымдын блоктоосуз:

  5. Токтотуу жана каталардын иштелиши: Корутина структураланган токтотуу жана каталардын жайылуусун колдойт:

    • Токтотуу:
      import kotlinx.coroutines.*
      
      fun cancellableTask() = GlobalScope.launch {
          try {
              repeat(1000) { i ->
                  println("Working $i ...")
                  delay(100) // токтотуучу функция, токтотууну сыйлайт
              }
          } catch (e: CancellationException) {
              println("Task was cancelled!")
          } finally {
              println("Cleaning up...")
          }
      }
      
      fun main() = runBlocking {
          val job = cancellableTask()
          delay(500) // Кыска убакыт күтүү
          job.cancelAndJoin() // Токтотуу жана аяктоону күтүү
      }
      
    • Каталар: launch менен — катасыз каталар программаны өчүрөт (Androidда — алдын ала орнотулган). async менен — каталар await() чакырганда чыгат. Толук көзөмөл үчүн CoroutineExceptionHandler же SupervisorJob колдонулат:
    import kotlinx.coroutines.*
    
    fun main() = runBlocking {
        val handler = CoroutineExceptionHandler { _, exception ->
            println("Caught exception: $exception")
        }
    
        val job = GlobalScope.launch(handler) { // иштетүүчү менен
            throw IllegalStateException("Something went wrong")
        }
        job.join() // аяктоону күтүү
    }