【问题标题】:kotlin flow onEach not being triggeredkotlin flow onEach 没有被触发
【发布时间】:2021-06-22 09:38:20
【问题描述】:

我正在尝试使用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 根本不起作用。并且收集工作一次,因为它应该。那么我应该如何监控/观察流量呢?

Logcat:

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

【问题讨论】:

    标签: kotlin kotlin-coroutines coroutine datastore kotlin-flow


    【解决方案1】:

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

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

    【讨论】:

    • 我已经尝试注释掉代码的其他部分,我只是将basicDataStore.serviceRunning.onEach { Log.d("d--mua-entry-service","$it current status - on each") } 保留在启动内,但它仍然不起作用......我的意思是它不会被触发..
    • 重读我第一段的后半部分。 :)
    猜你喜欢
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2017-11-22
    • 2012-06-03
    • 2019-11-07
    • 2018-09-01
    • 2018-12-03
    相关资源
    最近更新 更多