kotlin flow onEach 没有被触发

标签 kotlin kotlin-coroutines coroutine datastore kotlin-flow

我正在尝试使用 DataStore 存储值。


class BasicDataStore(context: Context) :
    PrefsDataStore(
        context,
        PREF_FILE_BASIC
    ),
    BasicImpl {

    override val serviceRunning: Flow<Boolean>
        get() = dataStore.data.map { preferences ->
            preferences[SERVICE_RUNNING_KEY] ?: false
        }

    override suspend fun setServiceRunningToStore(serviceRunning: Boolean) {
        dataStore.edit { preferences ->
            preferences[SERVICE_RUNNING_KEY] = serviceRunning
        }
    }

    companion object {
        private const val PREF_FILE_BASIC = "basic_preference"
        private val SERVICE_RUNNING_KEY = booleanPreferencesKey("service_running")
    }
}

@Singleton
interface BasicImpl {
    val serviceRunning: Flow<Boolean>
    suspend fun setServiceRunningToStore(serviceRunning: Boolean)
}

Service 中,试图监控该值,这是相应的代码:

private fun monitorNotificationService() {
        Log.d("d--mua-entry-service","entry")
        CoroutineScope(Dispatchers.IO).launch {
            Log.d("d--mua-entry-service","entry scope")
            basicDataStore.serviceRunning.collect{
                Log.d("d--mua-entry-service","$it current status - collect")
            }
            basicDataStore.serviceRunning.onEach {
                Log.d("d--mua-entry-service","$it current status - on each")
            }
        }
    }

EntryService 中:

    init {
        basicDataStore = BasicDataStore(this)
    }

但似乎 onEach 根本不起作用。并且 collect 只工作一次,这是应该的。那么我应该如何监控/观察流量呢?

日志:

2021-03-25 20:41:49.462 30761-30761/com.mua.roti D/d--mua-entry-service: entry
2021-03-25 20:41:49.465 30761-30900/com.mua.roti D/d--mua-entry-service: entry scope
2021-03-25 20:41:49.471 30761-30901/com.mua.roti D/d--mua-entry-service: false current status - collect

最佳答案

我没有使用过 DataStore,但我希望 Flow 是无限的,这意味着它永远不会完成收集,直到您取消协程。因此,将永远不会访问第一次调用 collect() 之后的任何代码。此外,当您调用 onEach 时,它只会返回另一个 Flow。在您收集返回的 Flow 之前,不会调用 onEach 中的代码。 onEach 用于将副作用添加到您稍后将进行的收集中。或者设置在使用 launchIn 收集它时要做什么。

创建一个不存储在属性中以供取消的 CoroutineScope 是一种代码味道。范围的要点是当关联组件的生命周期结束时,您可以取消它。如果您创建它并像这样丢弃您的引用,您将永远无法取消它的子级,因此调用 collect 将泄漏周围的类。如果您在 Android 上工作,您很少需要创建任何 CoroutineScope,因为该框架为各种生命周期组件(如 Activity、Fragment、ViewModel 和 LifecycleService)提供了作用域。

关于kotlin flow onEach 没有被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66802018/

相关文章:

java - 将java类文件转换为kotlin会出现编译错误

java - 将 java.time.LocalDate 与 postgres 日期进行比较时出现问题

android - Kotlin 的启动是在主线程还是后台线程中启动协程?

rust - 如何使用 Rust 中的 channel 菊花链线程?

python - 使用协程与线程时的吞吐量差异

java - 避免与 Kotlin 泛型内联

java - 在运行时在 android 中更改所有屏幕方向

接收流的Android单元测试 View 模型

swift - Kotlin 等价于 Swift 期望/ promise

使用workmanager的Android定期位置更新