launch — суштина, fire-and-forget покретање корутина и како ради

Аутор: IT Sectr Објављено: 2026-06-22 Време читања: 7 мин

launch — Coroutine Builder у Kotlin-у који покреће корутину без враћања резултата, враћајући Job објекат за управљање извршењем. Овај builder имплементира образац fire-and-forget: корутина почиње рад у позадинској нити и аутоматски се завршава. Према документацији JetBrains, 2024, launch је основни начин покретања паралелних задатака у Kotlin Coroutines.

Главне тачке

  • launch — builder за покретање корутина без враћања резултата (fire-and-forget)
  • Job — објекат за управљање корутином са методама cancel(), join(), isActive
  • launch се интегрише са CoroutineScope за аутоматско отказивање подређених корутина
  • CoroutineStart.LAZY омогућава одлагање покретања до експлицитног позива start() или join()
  • launch у Android-у се користи за чување у бази, мрежне позиве и ажурирање UI-ја

Шта је launch у Kotlin Coroutines?

launch — је функција проширења Kotlin-а, доступна преко import kotlinx.coroutines, која креира нову корутину у задатом CoroutineScope-у. За разлику од обичних функција, код унутар launch-а се извршава конкурентно — корутина може да се суспендује (suspend) без блокирања нити и да се настави касније.

Launch builder је фундаментални градивни блок модела корутина у Kotlin-у. Он не враћа израчунату вредност, али враћа Job објекат који омогућава контролу извршења корутине. Све подређене корутине покренуте преко launch-а унутар друге корутине везане су за родитељску.

Синтакса и параметри launch-а

Launch builder је дефинисан као inline функција са неколико параметара: CoroutineScope, CoroutineContext, CoroutineStart и suspend-block. Параметри имају подразумеване вредности, што чини launch погодним за типичне сценарије.

kotlin
public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job

Параметар context прихвата CoroutineContext који комбинује диспечера, руковаоца изузецима и именовани елемент. Најчешће се преноси Dispatchers.IO, Dispatchers.Main или SupervisorJob за изолацију грешака.

Job и управљање животним циклусом

Job — повратни објекат који представља животни циклус корутине. Job може бити у стањима: New, Active, Completing, Completed, Cancelling, Cancelled. Свако стање одражава статус извршења и омогућава реакцију на промене.

kotlin
val job = CoroutineScope(Dispatchers.IO).launch {
    repeat(10) { i ->
        delay(1000L)
        println("Напредак: $i")
    }
}

println("Job је активан: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job је отказан: ${job.isCancelled}")

Job подржава хијерархију: ако се родитељска корутина откаже, све подређене се аутоматски отказују. SupervisorJob мења ово понашање — подређене корутине се не отказују при грешци једне од њих.

Структурисана конкурентност у launch-у

Структурисана конкурентност значи да се свака корутина покреће у одређеном CoroutineScope-у, и scope се не завршава док све подређене корутине не заврше рад. launch у потпуности подржава овај принцип — корутине покренуте унутар друге корутине су њене подређене.

Угнежђени launch позиви

При угнежђеном покретању launch-а формира се стабло корутина. Родитељска корутина чека завршетак свих подређених, што гарантује предвидљив редослед извршења и поједностављује управљање ресурсима.

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("Дете 1 завршено")
        }
        launch {
            delay(500L)
            println("Дете 2 завршено")
        }
        println("Сва деца завршена пре ове линије")
    }
}

Ово понашање се разликује од конкурентности засноване на нитима, где подређене нити нису везане за родитељску. У корутинама, родитељ се не завршава док сва деца не заврше рад.

Обрада изузетака у launch-у

Обрада изузетака у launch-у зависи од типа Job-а. За обичан Job, изузеци се шире на родитељску корутину и отказују је. За SupervisorJob или SupervisorScope, изузеци су изоловани — грешка једне подређене корутине не утиче на остале.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("Ухваћено: ${e.message}")
    }
}
scope.launch {
    println("Ово још увек ради захваљујући SupervisorJob-у")
}

За глобалну обраду нехваћених изузетака користи се CoroutineExceptionHandler. Он хвата изузетке који нису обрађени унутар корутине и омогућава логирање грешке без краш-а апликације.

Примери коришћења launch-а у Android-у

У Android-у, launch се широко користи: од ViewModel-а до WorkManager-а. Главни образац је коришћење lifecycleScope у Fragment-у и viewModelScope у ViewModel-у за аутоматско отказивање корутина при завршетку животног циклуса компоненте.

kotlin
class ProfileViewModel : ViewModel() {
    private val repository = UserRepository()

    fun loadProfile(userId: String) {
        viewModelScope.launch(Dispatchers.IO) {
            val profile = repository.fetchProfile(userId)
            withContext(Dispatchers.Main) {
                _profileState.update { it.copy(profile = profile) }
            }
        }
    }
}

viewModelScope аутоматски отказује корутине при уништењу ViewModel-а. Ово елиминише цурење меморије и гарантује да се позадинске операције не настављају након губитка контекста. Додатно, може се користити withContext за пребацивање између диспечера.

Често постављана питања

По чему се launch разликује од async у Kotlin Coroutines?

launch враћа Job и не враћа резултат извршења, док async враћа Deferred<T> за добијање резултата. launch се користи за fire-and-forget операције, async — када треба сачекати и искористити повратну вредност.

Како отказати корутину покренуту преко launch-а?

Позовите job.cancel() на сачуваном Job објекту. За групно отказивање, откажите цео CoroutineScope преко scope.cancel(). Корутина мора бити кооперативна — проверавати isActive или користити проверљиве suspend функције.

Шта учинити ако launch баци изузетак?

Користите try-catch унутар launch блока или проследите CoroutineExceptionHandler у CoroutineContext. За изолацију грешака користите SupervisorJob — тада изузетак у једној подређеној корутини неће отказати остале.

Може ли се launch покренути без CoroutineScope-а?

Не, launch је функција проширења CoroutineScope-а. Без scope-а, корутина неће моћи да следи принцип структурисане конкурентности. Користите GlobalScope.launch опрезно — ово ствара корутину без везивања за животни циклус.

Колико launch корутина се може покренути истовремено?

Број је ограничен пулом нити диспечера. Dispatchers.Default користи број нити једнак броју CPU језгара. Dispatchers.IO подржава до 64 нити. При покретању већег броја корутина, one се стављају у ред чекања.

Резиме

  • launch — главни builder за fire-and-forget корутине, који враћа Job објекат
  • Job пружа методе управљања: cancel(), join(), isActive, isCancelled, isCompleted
  • Структурисана конкурентност гарантује отказивање подређених корутина при отказивању родитељске
  • Обрада изузетака зависи од типа Job-а: обични шири грешке, SupervisorJob изолује
  • lifecycleScope и viewModelScope — готовa решења за покретање launch-а у Android-у
  • CoroutineStart.LAZY одлаже покретање до експлицитног позива start() или join()
  • launch у Android-у се примењује за мрежне захтеве, упис у базу, аналитику и кеширање

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође