0Pricing
Kotlin Academy · Ders

shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme

Paylaşım işleçleriyle soğuk Flow'ları sıcak akışlara dönüştürün.

shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme, CoddyKit'te ücretsiz bir Kotlin Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Kotlin Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Kotlin Academy kursu toplamda 4 dersten oluşur.

Soğuk ve Sıcak Akışlar

Soğuk akışlar her toplayıcı için yeniden başlar; sıcak akışlar tek bir kaynak aboneliğini paylaşır. Soğuk akışı sıcak akışa dönüştürmek, birden çok toplayıcı abone olduğunda gereksiz çalışmayı önler.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun expensiveFlow() = flow {
    println("Starting upstream work")  // runs once if shared
    repeat(3) { delay(100); emit(it) }
}
fun main() = runBlocking {
    val cold = expensiveFlow()
    // Two collectors = two executions:
    launch { cold.collect { } }
    launch { cold.collect { } }
    delay(500)
    coroutineContext.cancelChildren()
}

shareIn Temelleri

flow.shareIn(scope, started, replay), soğuk bir akışı SharedFlow'a dönüştürür ve tek bir kaynak aboneliğini paylaşır.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val cold = flow {
        println("Upstream started once")
        repeat(5) { delay(100); emit(it) }
    }
    val hot = cold.shareIn(this, SharingStarted.Eagerly, replay = 0)
    launch { hot.collect { println("A: $it") } }
    launch { hot.collect { println("B: $it") } }
    delay(600)
    coroutineContext.cancelChildren()
}

stateIn Temelleri

flow.stateIn(scope, started, initialValue), akışı StateFlow'a dönüştürür — her zaman bir değeri vardır ve 1 değeri yeniden yayınlar.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val cold = flow { delay(100); emit(42) }
    val state: StateFlow<Int> = cold.stateIn(
        scope = this,
        started = SharingStarted.Eagerly,
        initialValue = 0
    )
    println(state.value)  // 0 immediately
    delay(200)
    println(state.value)  // 42 after upstream emits
    coroutineContext.cancelChildren()
}

SharingStarted için İstekli Başlatma

İstekli: kaynak akış, shareIn/stateIn çağrıldığında abonelerden bağımsız olarak hemen başlar.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = flow {
        println("Eagerly started")
        emit(1)
    }.shareIn(this, SharingStarted.Eagerly)
    // Upstream already running even before any collect
    delay(50)
    launch { flow.collect { println(it) } }
    delay(100)
    coroutineContext.cancelChildren()
}

SharingStarted için Tembel Başlatma

Tembel: kaynak akış ilk abone olduğunda başlar ve abonelerin sayısı sıfıra düşse bile hiç durmaz.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = flow {
        println("Lazily started on first subscriber")
        repeat(3) { delay(100); emit(it) }
    }.shareIn(this, SharingStarted.Lazily, replay = 1)
    delay(50)  // no subscriber yet — not started
    launch { flow.collect { println(it) } }  // triggers start
    delay(400)
    coroutineContext.cancelChildren()
}

SharingStarted.WhileSubscribed

WhileSubscribed(stopTimeout): kaynak akış ilk abone katıldığında başlar, son abone ayrıldıktan stopTimeout ms sonra durur. ViewModels için idealdir.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = flow {
        println("Started")
        repeat(10) { delay(100); emit(it) }
    }.shareIn(this, SharingStarted.WhileSubscribed(500))
    val job = launch { flow.collect { print("$it ") } }
    delay(300)
    job.cancel()    // subscriber left
    delay(200)      // within 500ms stop timeout — still running
    launch { flow.collect { print("resume $it ") } }
    delay(500)
    coroutineContext.cancelChildren()
}

Tipik ViewModel Deseni

Android ViewModels içinde, depodaki akışları stateIn(viewModelScope, WhileSubscribed(5000), initialValue) ile dönüştürerek paylaşın ve yapılandırma değişikliklerinden sonra da koruyun.

import kotlinx.coroutines.flow.*
// In ViewModel:
// val uiState: StateFlow<UiState> = repository
//     .dataFlow()
//     .map { UiState.Success(it) }
//     .stateIn(
//         scope = viewModelScope,
//         started = SharingStarted.WhileSubscribed(5_000),
//         initialValue = UiState.Loading
//     )
fun main() { println("WhileSubscribed(5000) is the recommended ViewModel pattern") }

shareIn ve stateIn Karşılaştırması

shareIn → SharedFlow (geçerli değer yok, yapılandırılabilir yeniden oynatma). stateIn → StateFlow (her zaman bir değeri vardır, replay=1). Tüketicilerin geçerli bir duruma ihtiyaç duyup duymamasına göre seçim yapın.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val cold = (1..3).asFlow().map { it * 10 }

    // SharedFlow — no initial value:
    val shared: SharedFlow<Int> = cold.shareIn(this, SharingStarted.Eagerly, replay = 1)

    // StateFlow — always has a value:
    val state: StateFlow<Int> = cold.stateIn(this, SharingStarted.Eagerly, 0)

    delay(100)
    println("shared cache: ${shared.replayCache}")
    println("state value: ${state.value}")
    coroutineContext.cancelChildren()
}

Yeniden Oynatma Önbelleği Dengeleri

Daha yüksek yeniden oynatma değeri, geç abone olanların daha fazla geçmiş görmesini sağlar; ancak daha fazla bellek kullanılır. Kullanıcı arayüzü durumu için replay=1 (stateIn) yeterlidir. Olay günlükleri için daha yüksek bir değer gerekebilir.

import kotlinx.coroutines.flow.*
// replay=0: no history, only future events
// replay=1: last value (equivalent to stateIn)
// replay=N: last N events — use for message feeds, logs

// Trade-off: memory vs subscriber freshness
fun main() { println("Choose replay based on late-subscriber requirements") }

Paylaşılmayan Akış Riski

Paylaşım olmadığında her Compose toplayıcısı veya ViewModel gözlemcisi kaynak akışı yeniden çalıştırır — gereksiz ağ çağrıları ve veritabanı sorguları oluşur. Maliyeti yüksek akışları her zaman paylaşın.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun expensiveApi() = flow {
    println("API CALL")  // without sharing: once per collector
    emit("data")
}
fun main() = runBlocking {
    val shared = expensiveApi().shareIn(this, SharingStarted.Lazily, replay = 1)
    launch { shared.collect { } }  // one API call, shared
    launch { shared.collect { } }  // same emission
    delay(200)
    coroutineContext.cancelChildren()
}

Paylaşım Sırasında Kaynakların Temizlenmesi

Paylaşılan akışın kapsamı iptal edildiğinde kaynak akış iptal edilir ve finally blokları çalışır — kaynaklar düzgün biçimde temizlenir.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun resourceFlow() = flow {
    try { repeat(10) { delay(100); emit(it) } }
    finally { println("Upstream cleaned up") }
}
fun main() = runBlocking {
    val scope = CoroutineScope(SupervisorJob())
    val shared = resourceFlow().shareIn(scope, SharingStarted.Eagerly)
    launch { shared.collect { print("$it ") } }
    delay(250)
    scope.cancel()  // upstream cleanup runs
    delay(100)
}

Hızlı Kontrol

Android ViewModels için hangi SharingStarted stratejisi önerilir?

Özet

shareIn, akışı SharedFlow'a; stateIn ise StateFlow'a dönüştürür. Kaynakları korumak için ViewModels içinde WhileSubscribed kullanın. Paylaşım, birden çok toplayıcı abone olduğunda kaynak akışın gereksiz yere yeniden çalıştırılmasını önler.

Sıkça Sorulan Sorular

“shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme” dersi ücretsiz mi?

Evet — “shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Kotlin Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Kotlin Academy kursu toplamda 4 dersten oluşur.

“shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme” dersinde ne öğreneceğim?

Paylaşım işleçleriyle soğuk Flow'ları sıcak akışlara dönüştürün. Kotlin Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

Kotlin Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te Kotlin Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.

“shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu Kotlin Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her Kotlin Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. StateFlow: Kullanıcı Arayüzü için Sıcak Durum Tutucusu
  2. SharedFlow: Olay Veri Yolları ve Tek Seferlik Olaylar
  3. shareIn ve stateIn ile Soğuk Flow'u Sıcağa Dönüştürme
  4. Turbine ile StateFlow ve SharedFlow Sınaması
← Kotlin Academy Sayfasına Dön