我有一些代码,应该将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)
}
}
然后,我观察到令牌,用户标识,公司标识的此首选项,然后登录,但是有些奇怪,因为我需要构建应用程序三遍,例如更改令牌不会导致令牌流发出任何东西,然后第二次新用户标识不会导致用户标识流发出任何东西,然后在第三次登录后,我可以注销/登录,并且可以正常工作。注销时,我将清除prefs令牌,userId,companyId中的所有3个属性存储。
答案 0 :(得分:8)
对于callbackFlow
:
您不能在回调中将emit()
用作简单的Flow
(因为它是suspend
函数)。因此,callbackFlow
为您提供了一种使用offer()
选项的同步方式。
示例:
fun observeData() = flow {
myAwesomeInterface.addListener{ result ->
emit(result) // NOT ALLOWED
}
}
因此,协程为您提供了callbackFlow
的选择:
fun observeData() = callbackFlow {
myAwesomeInterface.addListener{ result ->
offer(result) // ALLOWED
}
awaitClose{ myAwesomeInterface.removeListener() }
}
对于channelFlow
:
与Flow
基本的区别在于documentation:
使用具有默认缓冲区大小的通道。使用缓冲区 运算符在结果流上指定用户定义的值并 控制数据生成速度快于消费速度时发生的情况,即 控制背压行为。
offer()
仍然代表同一件事。这只是suspending
或emit()
send()
方式)
我建议您检查Romans Elizarov blog以获得更详细的信息,尤其是this帖子。
关于您的代码,对于callbackFlow
,您不需要协程启动:
coroutineScope.launch {
send(key)
//offer(key)
}
只需使用offer()