kotlin flow onEach 没有被触发

Mai*_*sad 7 datastore coroutine kotlin kotlin-coroutines 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)
}
Run Code Online (Sandbox Code Playgroud)

在 a 中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")
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

EntryService

    init {
        basicDataStore = BasicDataStore(this)
    }
Run Code Online (Sandbox Code Playgroud)

但似乎 onEach 根本不起作用。收集工作一次就可以了,这是应该的。那么我应该如何监控/观察流量呢?

日志猫:

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
Run Code Online (Sandbox Code Playgroud)

Ten*_*r04 6

我没有使用过 DataStore,但我预计 Flow 是无限的,这意味着它永远不会完成收集,直到您取消协程。collect()因此,永远不会到达第一次调用以下的任何代码。此外,当您调用 时onEach,它只是返回另一个 Flow。onEach在您收集返回的 Flow 之前,不会调用中的代码。onEach用于为您稍后要做的收集添加副作用。或者也可以设置在launchIn收集数据时要执行的操作。

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