launch — istota, fire-and-forget uruchamianie korutyn i jak działa

Autor: IT Sectr Opublikowano: 2026-06-22 Czas czytania: 7 min

launch — Coroutine Builder w Kotlin, który uruchamia korutynę bez zwracania wyniku, zwracając obiekt Job do zarządzania wykonaniem. Ten builder implementuje wzorzec fire-and-forget: korutyna rozpoczyna pracę w wątku tła i automatycznie się kończy. Według dokumentacji JetBrains, 2024, launch jest głównym sposobem uruchamiania zadań równoległych w Kotlin Coroutines.

Najważniejsze

  • launch — builder do uruchamiania korutyn bez zwracania wyniku (fire-and-forget)
  • Job — obiekt zarządzania korutyną z metodami cancel(), join(), isActive
  • launch integruje się z CoroutineScope do automatycznego anulowania korutyn potomnych
  • CoroutineStart.LAZY pozwala opóźnić uruchomienie do jawnego wywołania start() lub join()
  • launch w Android jest używany do zapisu w BD, wywołań sieciowych i aktualizacji UI

Czym jest launch w Kotlin Coroutines?

launch — to funkcja rozszerzająca Kotlin, dostępna przez import kotlinx.coroutines, która tworzy nową korutynę w zadanym CoroutineScope. W przeciwieństwie do zwykłych funkcji, kod wewnątrz launch wykonuje się współbieżnie — korutyna może się zawieszać (suspend) bez blokowania wątku i wznawiać później.

Builder launch jest fundamentalnym blokiem konstrukcyjnym modelu korutyn w Kotlin. Nie zwraca obliczonej wartości, ale zwraca obiekt Job, umożliwiający kontrolowanie wykonania korutyny. Wszystkie korutyny potomne uruchomione przez launch wewnątrz innej korutyny są powiązane z rodzicielską.

Składnia i parametry launch

Builder launch jest zdefiniowany jako funkcja inline z kilkoma parametrami: CoroutineScope, CoroutineContext, CoroutineStart i suspend-block. Parametry mają wartości domyślne, co czyni launch wygodnym dla typowych scenariuszy.

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

Parametr context przyjmuje CoroutineContext, łączący dyspozytora, obsługę wyjątków i nazwany element. Najczęściej przekazywany jest Dispatchers.IO, Dispatchers.Main lub SupervisorJob do izolacji błędów.

Job i zarządzanie cyklem życia

Job — zwracany obiekt reprezentujący cykl życia korutyny. Job może znajdować się w stanach: New, Active, Completing, Completed, Cancelling, Cancelled. Każdy stan odzwierciedla status wykonania i pozwala reagować na zmiany.

kotlin
val job = CoroutineScope(Dispatchers.IO).launch {
    repeat(10) { i ->
        delay(1000L)
        println("Postęp: $i")
    }
}

println("Job jest aktywny: ${job.isActive}")
delay(2500L)
job.cancel()
println("Job jest anulowany: ${job.isCancelled}")

Job wspiera hierarchię: jeśli rodzicielska korutyna zostanie anulowana, wszystkie potomne są automatycznie anulowane. SupervisorJob zmienia to zachowanie — korutyny potomne nie są anulowane przy błędzie jednej z nich.

Ustrukturyzowana współbieżność w launch

Ustrukturyzowana współbieżność oznacza, że każda korutyna jest uruchamiana w określonym CoroutineScope, a scope nie zakończy się, dopóki wszystkie korutyny potomne nie zakończą pracy. launch w pełni wspiera tę zasadę — korutyny uruchomione wewnątrz innej korutyny są jej potomnymi.

Zagnieżdżone wywołania launch

Przy zagnieżdżonym uruchamianiu launch powstaje drzewo korutyn. Rodzicielska korutyna oczekuje na zakończenie wszystkich potomnych, co gwarantuje przewidywalną kolejność wykonania i upraszcza zarządzanie zasobami.

kotlin
fun main() = runBlocking {
    launch {
        launch {
            delay(1000L)
            println("Potomny 1 zakończony")
        }
        launch {
            delay(500L)
            println("Potomny 2 zakończony")
        }
        println("Wszystkie potomne zakończone przed tą linią")
    }
}

To zachowanie różni się od współbieżności opartej na wątkach, gdzie wątki potomne nie są powiązane z rodzicielskim. W korutynach rodzic nie zakończy się, dopóki wszystkie dzieci nie zakończą pracy.

Obsługa wyjątków w launch

Obsługa wyjątków w launch zależy od typu Job. W przypadku zwykłego Job wyjątki rozprzestrzeniają się na rodzicielską korutynę i anulują ją. Dla SupervisorJob lub SupervisorScope wyjątki są izolowane — błąd jednej korutyny potomnej nie wpływa na pozostałe.

kotlin
val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
scope.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("Przechwycono: ${e.message}")
    }
}
scope.launch {
    println("To wciąż działa dzięki SupervisorJob")
}

Do globalnej obsługi nieprzechwyconych wyjątków używa się CoroutineExceptionHandler. Przechwytuje on wyjątki, które nie zostały obsłużone wewnątrz korutyny, i umożliwia zalogowanie błędu bez crasha aplikacji.

Przykłady użycia launch w Android

W Android launch jest używany wszechobecnie: od ViewModel do WorkManager. Główny wzorzec — użycie lifecycleScope we Fragment i viewModelScope w ViewModel do automatycznego anulowania korutyn przy zakończeniu cyklu życia komponentu.

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 automatycznie anuluje korutyny przy zniszczeniu ViewModel. Eliminuje to wycieki i gwarantuje, że operacje w tle nie są kontynuowane po utracie kontekstu. Dodatkowo można użyć withContext do przełączania między dyspozytorami.

Często zadawane pytania

Czym różni się launch od async w Kotlin Coroutines?

launch zwraca Job i nie zwraca wyniku wykonania, a async zwraca Deferred<T> do uzyskania wyniku. launch jest używany do operacji fire-and-forget, async — gdy trzeba poczekać i użyć zwróconej wartości.

Jak anulować korutynę uruchomioną przez launch?

Wywołaj job.cancel() na zapisanym obiekcie Job. Do grupowego anulowania anuluj cały CoroutineScope przez scope.cancel(). Korutyna musi być kooperatywna — sprawdzać isActive lub używać sprawdzalnych funkcji suspend.

Co zrobić, jeśli launch wyrzucił wyjątek?

Użyj try-catch wewnątrz bloku launch lub przekaż CoroutineExceptionHandler w CoroutineContext. Do izolacji błędów użyj SupervisorJob — wtedy wyjątek w jednej korutynie potomnej nie anuluje pozostałych.

Czy można uruchomić launch bez CoroutineScope?

Nie, launch — funkcja rozszerzająca CoroutineScope. Bez scope korutyna nie będzie mogła przestrzegać zasady ustrukturyzowanej współbieżności. Używaj GlobalScope.launch ostrożnie — tworzy to korutynę bez powiązania z cyklem życia.

Ile korutyn launch można uruchomić jednocześnie?

Ilość jest ograniczona pulą wątków dyspozytora. Dispatchers.Default używa liczby wątków równej liczbie rdzeni CPU. Dispatchers.IO obsługuje do 64 wątków. Przy uruchamianiu większej liczby korutyn są one kolejkowane.

Podsumowanie

  • launch — główny builder dla korutyn fire-and-forget, zwracający obiekt Job
  • Job udostępnia metody zarządzania: cancel(), join(), isActive, isCancelled, isCompleted
  • Ustrukturyzowana współbieżność gwarantuje anulowanie korutyn potomnych przy anulowaniu rodzicielskiej
  • Obsługa wyjątków zależy od typu Job: zwykły rozprzestrzenia błędy, SupervisorJob izoluje
  • lifecycleScope i viewModelScope — gotowe rozwiązania do uruchamiania launch w Android
  • CoroutineStart.LAZY opóźnia uruchomienie do jawnego wywołania start() lub join()
  • launch w Android jest stosowany do zapytań sieciowych, zapisu w BD, analityki i buforowania

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również