Kotlin Flow&SharedFlow&StateFlow

本文探讨了Kotlin中的Flow、SharedFlow与StateFlow,介绍了它们的特点、区别和使用场景,重点讲解了数据更新机制、生命周期管理和懒加载特性。通过实例演示了如何在Activity和ViewModel中运用这些工具,并提供了代码下载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Kotlin Flow&SharedFlow&StateFlow

Flow

  • Flow 是冷流,只有调用 collect() 后才会触发数据生产逻辑。
  • 无始化值。
  • 每个收集者独立处理数据流。
  • 支持背压操作。
val flow = flow {
    emit("hello")
    delay(2000L)
    emit("world")
}
flow.collect {
    Log.e("TAG", "collector1: $it")
}
flow.collect {
    Log.e("TAG", "collector2: $it")
}

// collector1: hello
// collector1: world
// collector2: hello
// collector2: world

SharedFlow

  • SharedFlow 是热流,没有收集者也会执行数据生成逻辑。
  • 无初始值。
  • 支持多个收集者共享数据。
  • 支持配置历史值,通过 replay 参数。

SharedFlow构造函数

public fun <T> MutableSharedFlow(
    replay: Int = 0,  
    extraBufferCapacity: Int = 0,  
    onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND // 
):
  • replay:缓存历史数据个数,为0表示不缓存历史数据。
  • extraBufferCapacity:减去replay后的缓冲空间。缓冲器总容量=replay+extraBufferCapacity。
  • onBufferOverflow:缓冲区满时的策略,默认为挂起。

MainActivity:

class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycleScope.launch {
            viewModel.flow.collect {
                Log.e("TAG", "collector1: $it")
            }

        }
        lifecycleScope.launch {
            viewModel.flow.collect {
                Log.e("TAG", "collector2: $it")
            }
        }
    }

    fun onClick(view: View) {
        viewModel.send()
    }
}

MainViewModel:

class MainViewModel : ViewModel() {
    private val _flow = MutableSharedFlow<String>(replay = 1)
    val flow = _flow.asSharedFlow()

    fun send() {
        viewModelScope.launch {
            _flow.emit("hello")
            _flow.emit("world")
        }
    }
}

replay

class MainViewModel : ViewModel() {
    private val _flow = MutableSharedFlow<String>(1 )
    val flow = _flow.asSharedFlow()

    fun send() {
        viewModelScope.launch {
            _flow.tryEmit("hello")
            _flow.tryEmit("world")
        }
    }
}

// collector1: hello
// collector2: hello

说明:当 replay 设置为 1 时,点击 send(),订阅者会收到1条数据。

class MainViewModel : ViewModel() {
    private val _flow = MutableSharedFlow<String>(1 )
    val flow = _flow.asSharedFlow()

    fun send() {
        viewModelScope.launch {
            _flow.tryEmit("hello")
            _flow.tryEmit("world")
        }
    }
}

// collector1: hello
// collector1: world
// collector2: hello
// collector2: world

说明:当 replay 设置为 2时,点击 send(),订阅者会收到2条数据。

StateFlow

  • StateFlow 是热流,没有收集者也会执行数据生成逻辑。
  • 必须设置初始值。
  • 自动去重,通过 equals() 方法判断新值与旧值是否相同,不同则触发更新。
  • 简化的 SharedFlow,等价于 replay=1onBufferOverflow=DROP_OLDESTSharedFlow

MainActivity:

class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        lifecycleScope.launch {
            viewModel.flow.collect {
                Log.e("TAG", "collector1: $it")
            }

        }
        lifecycleScope.launch {
            viewModel.flow.collect {
                Log.e("TAG", "collector2: $it")
            }
        }
    }

    fun onClick(view: View) {
        viewModel.send()
    }
}

// collector1: world
// collector2: world

MainViewModel:

class MainViewModel : ViewModel() {
    private val _flow = MutableStateFlow("")
    val flow = _flow.asStateFlow()

    fun send() {
        viewModelScope.launch {
            _flow.value = "hello"
            _flow.value = "world"
        }
    }
}

说明:点击 send() 方法,订阅者收到1条数据。

总结

FlowSharedFlowStateFlow
特征冷流热流热流
初始值
数据共享独立处理数据流共享数据流共享数据流
重播数据不支持配置replay仅保留最新值
场景单次异步操作,如:网络请求数据共享,如:全局通知UI状态管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值