概述
StateFlow
hold flow, 没有消费者进行消费的时候,生产者也可以生产数据(生产者在没有消费者订阅之前生产数据可能会丢失数据)。
class MainViewModel : ViewModel() {
private val _stateFlow = MutableStateFlow(0)
val stateFlow = _stateFlow.asStateFlow()
fun incrementCounter() {
_stateFlow.value += 1
}
}
In Compose:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FlowDemoTheme {
//val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
val viewModel = viewModel<MainViewModel>()
val count = viewModel.stateFlow.collectAsState(initial = 10)
Box(modifier = Modifier.fillMaxSize()) {
Button(onClick = { viewModel.incrementCounter() }) {
Text(text = "Counter: ${count.value}")
}
}
}
}
}
}
In Xml:
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
/*lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.stateFlow.collectLatest { number ->
binding.tvCounter.text = number.toString()
}
}
}*/
collectLatestLifecycleFlow(viewModel.stateFlow) { number ->
binding.tvCounter.text = number.toString()
}
}
}
fun <T> ComponentActivity.collectLatestLifecycleFlow(
flow: Flow<T>, collect: suspend (T) -> Unit) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
flow.collectLatest(collect)
}
}
}
SharedFlow
It is used to send one-time events
class MainViewModel : ViewModel() {
private val _sharedFlow = MutableSharedFlow<Int>()
val sharedFlow = _sharedFlow.asSharedFlow()
fun squareNumber(number: Int) {
viewModelScope.launch {
_sharedFlow.emit(number * number)
}
}
init {
println("FLOW: STARTED")
viewModelScope.launch {
sharedFlow.collect {
delay(2000L)
println("FIRST FLOW: The received number is $it")
}
}
viewModelScope.launch {
sharedFlow.collect {
delay(3000L)
println("SECOND FLOW: The received number is $it")
}
}
// 由于SharedFlow是热流,必须是在声明collector之后调用,否则会丢失数据
squareNumber(3)
}
}
Use cache to cache the emitted data:
class MainViewModel : ViewModel() {
private val _sharedFlowCached = MutableSharedFlow<Int>(replay = 5)
val sharedFlowCached = _sharedFlowCached.asSharedFlow()
fun squareNumberCached(number: Int) {
viewModelScope.launch {
_sharedFlowCached.emit(number * number)
_sharedFlowCached.emit(number + number)
}
}
init {
squareNumberCached(3)
println("FLOW: STARTED")
viewModelScope.launch {
sharedFlowCached.collect {
delay(1000L)
println("FIRST FLOW: The received number is $it")
}
}
viewModelScope.launch {
sharedFlowCached.collect {
delay(3000L)
println("SECOND FLOW: The received number is $it")
}
}
}
}
How to use shared flow in Activity?
In Compose:
class MainActivity : ComponentActivity() {
private val viewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FlowDemoTheme {
LaunchedEffect(key1 = true) {
viewModel.sharedFlow.collect { number ->
}
}
...
}
}
}
}
In Xml:
fun <T> ComponentActivity.collectLifecycleFlow(
flow: Flow<T>, collect: suspend (T) -> Unit) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
flow.collect(collect)
}
}
}
StateFlow vs SharedFlow
State flow is used to keep state to keep values that you also want to re-emit on screen.
Shared flow is used to for one-time events that you don’t want to hide the keyboard again.
最后
以上就是迷路羽毛为你收集整理的Kotlin StateFlow&SharedFlow(二)的全部内容,希望文章能够帮你解决Kotlin StateFlow&SharedFlow(二)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复