kotlin - Android Kotlin Coroutines:flow、callbackFlow、channelFlow、...其他流构造函数有什么区别
问题描述
我的代码应该通过流将 SharedPreferences 更改为可观察的存储,所以我有这样的代码
internal val onKeyValueChange: Flow<String> = channelFlow {
val callback = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
coroutineScope.launch {
//send(key)
offer(key)
}
}
sharedPreferences.registerOnSharedPreferenceChangeListener(callback)
awaitClose {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(callback)
}
}
或这个
internal val onKeyValueChange: Flow<String> = callbackFlow {
val callback = SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
coroutineScope.launch {
send(key)
//offer(key)
}
}
sharedPreferences.registerOnSharedPreferenceChangeListener(callback)
awaitClose {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(callback)
}
}
然后我观察token、userId、companyId的这个偏好,然后登录但是有一个奇怪的事情,因为我需要构建应用程序三次,比如更改token不会导致tokenFlow发出任何东西,然后第二次新的userId不会导致userIdFlow发出任何东西,然后在第三次登录后我可以注销/登录并且它可以工作。注销时,我正在清除 prefs 令牌、userId、companyId 中的所有 3 个属性存储。
解决方案
对于callbackFlow
:
您不能在回调中emit()
用作简单的Flow
(因为它是一个suspend
函数)。因此callbackFlow
,该选项为您提供了一种同步的方式来执行此操作trySend()
。
例子:
fun observeData() = flow {
myAwesomeInterface.addListener{ result ->
emit(result) // NOT ALLOWED
}
}
因此,协程为您提供了以下选项callbackFlow
:
fun observeData() = callbackFlow {
myAwesomeInterface.addListener{ result ->
trySend(result) // ALLOWED
}
awaitClose{ myAwesomeInterface.removeListener() }
}
对于channelFlow
:
文档Flow
中描述了它和基本的主要区别:
使用具有默认缓冲区大小的通道。在结果流上使用缓冲区运算符来指定用户定义的值,并控制当数据生成速度快于消耗时发生的情况,即控制背压行为。
trySend()
仍然代表同样的事情。这只是一种同步方式(一种非suspending
方式)emit()
或send()
我建议您查看 Romans Elizarov博客以获取更多详细信息,尤其是这篇文章。
关于您的代码,因为callbackFlow
您不需要协程启动:
coroutineScope.launch {
send(key)
//trySend(key)
}
只需使用trySend()
推荐阅读
- node.js - 从不同的集合中获取数据,在猫鼬中没有任何关系
- python-3.x - 使用 fastai 库执行用于图像识别的 cnn 模型时出现运行时错误
- github - 如何允许 GitHub 贡献者添加更多贡献者?
- c - C:从 char 数组打印会产生错误的字符
- python - 如何使用 boto3 从 S3 将数据写入 RDS
- google-analytics - 如何在谷歌 BigQuery 中复制谷歌分析段?
- linux - 如何在ansible中获得一个随机未使用的端口
- firebase - Firebase Firestore 中的管理员通知
- c - 有效签证:4222222222222 输出无效
- javascript - 如何获得 Express JS substr?