Kotlin Academy · Pelajaran

StateFlow: Penampung Status Aktif untuk UI

Gunakan StateFlow sebagai wadah status reaktif dan amati di ViewModels.

Pelajaran 1 dari 413 langkah

StateFlow: Penampung Status Aktif untuk UI adalah pelajaran Kotlin Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Kotlin Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa Itu StateFlow?

StateFlow adalah aliran panas yang menyimpan keadaan, selalu memiliki nilai, dan memancarkan pembaruan kepada semua pengumpul. StateFlow menggantikan LiveData dalam arsitektur Kotlin modern.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val stateFlow = MutableStateFlow(0)  // initial value
    println("Current: ${stateFlow.value}")
    stateFlow.value = 42
    println("Updated: ${stateFlow.value}")
}

MutableStateFlow vs StateFlow

MutableStateFlow adalah implementasi yang dapat diubah dan digunakan secara internal. Tampilkan StateFlow (hanya-baca) kepada pengamat eksternal dengan melakukan cast atau menggunakan .asStateFlow().

import kotlinx.coroutines.flow.*
class CounterViewModel {
    private val _count = MutableStateFlow(0)  // mutable internally
    val count: StateFlow<Int> = _count.asStateFlow()  // read-only externally
    fun increment() { _count.value++ }
    fun decrement() { _count.value-- }
}

Mengumpulkan StateFlow

Kumpulkan StateFlow seperti aliran lainnya. Nilai terbaru langsung dipancarkan saat pengumpulan dimulai.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val state = MutableStateFlow("loading")
    launch {
        state.collect { println("State: $it") }
    }
    delay(50); state.value = "success"
    delay(50); state.value = "idle"
    delay(50)
    coroutineContext.cancelChildren()
}

StateFlow Menggabungkan Nilai yang Sama

StateFlow hanya memancarkan nilai saat nilainya berubah. Jika Anda menetapkan nilai yang sama dua kali, hanya satu emisi yang terjadi—nilai duplikat yang berurutan digabungkan.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val flow = MutableStateFlow("A")
    launch {
        flow.collect { println("Received: $it") }
    }
    delay(50)
    flow.value = "A"  // no emission — same value
    flow.value = "B"  // emits
    flow.value = "B"  // no emission — same value
    flow.value = "C"  // emits
    delay(50)
    coroutineContext.cancelChildren()
}

StateFlow dalam ViewModel

Pola ViewModel kanonis: MutableStateFlow privat diubah oleh logika bisnis, sedangkan StateFlow publik diamati oleh UI.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
sealed class UiState { object Loading : UiState(); data class Success(val data: String) : UiState(); data class Error(val msg: String) : UiState() }
class MyViewModel(scope: CoroutineScope) {
    private val _uiState = MutableStateFlow<UiState>(UiState.Loading)
    val uiState: StateFlow<UiState> = _uiState.asStateFlow()
    init {
        scope.launch {
            delay(100)  // simulate load
            _uiState.value = UiState.Success("Hello!")
        }
    }
}

Pembaruan Atomik

Gunakan update { } untuk memperbarui keadaan secara atomik berdasarkan nilai saat ini—hal yang penting untuk pembaruan secara bersamaan.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val counter = MutableStateFlow(0)
    List(100) {
        launch(Dispatchers.Default) {
            counter.update { it + 1 }  // thread-safe atomic update
        }
    }.forEach { it.join() }
    println("Counter: ${counter.value}")  // 100
}

compareAndSet untuk Pembaruan Optimistis

compareAndSet(expect, update) hanya menetapkan nilai baru jika nilai saat ini cocok dengan expect. Ini berguna untuk konkurensi optimistis.

import kotlinx.coroutines.flow.*
fun main() {
    val state = MutableStateFlow("idle")
    val changed = state.compareAndSet("idle", "loading")
    println("Changed: $changed, Value: ${state.value}")  // true, loading
    val changed2 = state.compareAndSet("idle", "error")  // won't change
    println("Changed: $changed2, Value: ${state.value}") // false, loading
}

StateFlow vs LiveData

StateFlow dapat digunakan tanpa siklus hidup Android. LiveData sadar siklus hidup, tetapi hanya tersedia di Android. Utamakan StateFlow untuk ViewModels KMP bersama.

import kotlinx.coroutines.flow.*
// StateFlow: pure Kotlin, works in commonMain
// val state = MutableStateFlow("value")

// LiveData: Android-only, lifecycle-aware
// val liveData = MutableLiveData("value")

// In Compose, collect StateFlow with:
// val state by viewModel.uiState.collectAsState()
fun main() { println("StateFlow: multiplatform; LiveData: Android-only") }

stateIn: Mengubah Aliran Dingin menjadi StateFlow

flow.stateIn(scope, started, initialValue) mengubah aliran dingin menjadi StateFlow panas dan membagikan satu langganan kepada semua pengumpul.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val cold = flow {
        println("Fetching...")
        delay(100)
        emit("data")
    }
    val hot: StateFlow<String> = cold.stateIn(
        scope = this,
        started = SharingStarted.Lazily,
        initialValue = "loading"
    )
    launch { hot.collect { println("A: $it") } }
    launch { hot.collect { println("B: $it") } }
    delay(200)
    coroutineContext.cancelChildren()
}

Strategi SharingStarted

Segera: langsung dimulai. Secara tertunda: dimulai saat pengumpul pertama berlangganan. WhileSubscribed(stopTimeout): berhenti saat tidak ada pengumpul dan dimulai kembali saat ada yang berlangganan.

import kotlinx.coroutines.flow.*
// Eagerly: upstream starts right away
// SharingStarted.Eagerly

// Lazily: waits for first subscriber
// SharingStarted.Lazily

// WhileSubscribed: stops 5s after last subscriber
// SharingStarted.WhileSubscribed(5000)

// Typical ViewModel usage:
// val uiState = repo.dataFlow.stateIn(viewModelScope, WhileSubscribed(5000), Loading)

Mengamati Keadaan Turunan

Turunkan StateFlow baru dari StateFlow yang sudah ada menggunakan map + stateIn. Aliran turunan diperbarui setiap kali sumbernya berubah.

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
fun main() = runBlocking {
    val count = MutableStateFlow(5)
    val doubled = count.map { it * 2 }.stateIn(this, SharingStarted.Eagerly, 10)
    println(doubled.value)  // 10
    count.value = 7
    delay(50)
    println(doubled.value)  // 14
    coroutineContext.cancelChildren()
}

Pemeriksaan Singkat

Apa yang dilakukan StateFlow saat Anda menetapkan nilai yang sama dua kali?

Ringkasan

StateFlow adalah aliran panas yang selalu memiliki nilai dan menggabungkan nilai yang sama. Gunakan MutableStateFlow secara internal dan tampilkan StateFlow secara eksternal. Gunakan pembaruan() untuk perubahan secara bersamaan dan stateIn() untuk mengubah aliran dingin.

Gratis untuk memulai

Belajar Kotlin dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
51
Pelajaran
203

Pertanyaan yang Sering Diajukan

Apakah pelajaran “StateFlow: Penampung Status Aktif untuk UI” gratis?

Ya — teks lengkap “StateFlow: Penampung Status Aktif untuk UI” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Kotlin Academy, upgrade ke CoddyKit PRO. Kursus Kotlin Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “StateFlow: Penampung Status Aktif untuk UI”?

Gunakan StateFlow sebagai wadah status reaktif dan amati di ViewModels. Kamu berlatih Kotlin Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Kotlin Academy?

Tidak diperlukan pengalaman sebelumnya. Kotlin Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “StateFlow: Penampung Status Aktif untuk UI” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Kotlin Academy ini?

Ya. Setiap pelajaran Kotlin Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. StateFlow: Penampung Status Aktif untuk UI
  2. SharedFlow: Bus Peristiwa dan Peristiwa Sekali Jalan
  3. Mengubah Flow Dingin Menjadi Aktif dengan shareIn dan stateIn
  4. Menguji StateFlow dan SharedFlow dengan Turbine
← Kembali ke Kotlin Academy