Flow是冷流。简单来说。如果Flow有了订阅者Collector以后,发射出来的值才会存在内存中,

这和懒加载的概念很像

与之相对的是热流,StateFlow和SharedFlow 是热流,在垃圾回收之前,都是存在内存之中,

并且处于活跃状态

StateFlow 是一个状态容器式可观察数据流,可以向其收集器发出当前状态更新和新状态更新,还可通过其value属性读取当前状态值。

和livedata很像。

Kotlin Flow 冷流 StateFlow 热流 StateFlow 的应用_ide

 

package com.example.android_flow_practice.viewmodel

import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow

class NumberViewModel : ViewModel() {
val number = MutableStateFlow(0)
fun increment() {
number.value++
}

fun deincrement() {
number.value--
}
}

fragment

package com.example.android_flow_practice.fragment

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.example.android_flow_practice.R
import com.example.android_flow_practice.databinding.FragmentArticleBinding
import com.example.android_flow_practice.databinding.FragmentNumberBinding
import com.example.android_flow_practice.viewmodel.ArticleViewModel
import com.example.android_flow_practice.viewmodel.NumberViewModel
import kotlinx.coroutines.flow.collect

class NumberFragment : Fragment() {
private val TAG = "NumberFragment"
private val viewModel: NumberViewModel by viewModels()

private val mBinding: FragmentNumberBinding by lazy {
FragmentNumberBinding.inflate(layoutInflater)
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return mBinding.root
}


override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mBinding.apply {
btAdd.setOnClickListener { viewModel.increment() }
btSubtraction.setOnClickListener { viewModel.deincrement() }
}
lifecycleScope.launchWhenCreated {
viewModel.number.collect {
mBinding.tvText.text = it.toString()
}
}
}
}

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".fragment.NumberFragment">

<TextView
android:id="@+id/tv_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="10dp"
android:text="0"
android:textAlignment="center" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<Button
android:id="@+id/bt_add"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="+" />

<Button
android:id="@+id/bt_subtraction"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="-" />
</LinearLayout>

</LinearLayout>