https://www.youtube.com/watch?v=M8YtV47kaqA&t=607s
pl学习视频
什么是冷流?
fun fibonacci(): Flow<BigInteger> = flow {var x = BigInteger.ZEROvar y = BigInteger.ONEwhile (true) {println("fibonacci while $x")emit(x)x = y.also {y += x}}}
这时候试着运行
fun testJob() {testJob = viewModelScope.launch {repository.fibonacci()}
虽然运行了fibonacci(),但是没有任何的打印。原因是,冷流是只有有订阅者后,才开始发送数据。所以需要collect之后,才有数据
fun testJob() {testJob = viewModelScope.launch {var i = 0repository.fibonacci().take(100).collect {i++println("fibonacci $it")println("fibonacci $i")}}}
像之前的例子也有说到callbackflow,他也是一个冷流,之前有个例子,监听网络状态
fun networkAvailability(context: Context) = callbackFlow {val callback = object : ConnectivityManager.NetworkCallback() {override fun onAvailable(network: Network) {super.onAvailable(network)println("network send true")trySend(true)}override fun onLost(network: Network) {super.onLost(network)println("network send false")trySend(false)}}val manager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager//注册println("network register")manager.registerNetworkCallback(NetworkRequest.Builder().addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(), callback)awaitClose {//取消注册println("network unregister")manager.unregisterNetworkCallback(callback)}}
我们监听这个flow
val flow = remember { viewModel.networkAvailability(applicationContext) }val status1 = flow.collectAsStateWithLifecycle(false)val status2 = flow.collectAsStateWithLifecycle(false)
看下打印情况
可以看到网络监听注册了两次,所以对冷流的数据收集是独立的。这不是我们想要的,我们希望只监听一次,然后只关心最新的数据,这个数据可以多个观察者共享,这时候,就希望把冷流变成热流,shareIn
val rememberCoroutineScope = rememberCoroutineScope()val flow = remember { viewModel.networkAvailability(applicationContext).shareIn(rememberCoroutineScope,SharingStarted.Eagerly)}val status1 = flow.collectAsStateWithLifecycle(false)val status2 = flow.collectAsStateWithLifecycle(false)
只是将flow转换 shareIn之后
只注册了一次
这样就可以避免重复的数据发送
shareIn 和 stateIn区别在于是否缓存最新的值,后续还有区分的视频,如果是事件类型用shareflow像消息提示,snackbar,
如果是UI状态,用stateIn,只关心最新的值