【问题标题】:Android callback for a coroutine flow is not fired未触发协程流的 Android 回调
【发布时间】:2021-05-24 07:36:27
【问题描述】:

我有一项服务,其中数据由 MutableLiveData 支持并通过流向外部公开。

@ApplicationScope
@Singleton
class UserProfileServiceImpl : UserProfileService {

    private var userLiveData: MutableLiveData<UserProfile?> = MutableLiveData()

    override fun currentUser() = userLiveData.value

    override fun updatePoints(points: Int) {
       val user = currentUser()
           ?: throw IllegalAccessException("user is not authenticated")

       user.points = points
       userLiveData.postValue(user)
    }

    override suspend fun currentUserFlow(): Flow<UserProfile?> =
        callbackFlow {
            userLiveData.observeForever {
                offer(it)
            }
        }
}

然后我监听片段视图模型的变化并且回调没有被调用

class ViewModel: ViewModel() {
    fun startListeningToService() {
        viewModelScope.launch {
            profileService.currentUserFlow().collect {
                // This is not getting fired
                // Send data to another liveData that the activity is listening to
            }
        }
    }
}
  1. 我让这件事变得复杂了吗?感觉像是经过了很多层 从 1 点到另一个点的数据?使用 a 真的有优势吗 流到这里?感觉就像只是使用 LiveData 会很多 更简单,不需要在两者之间进行翻译
  2. 即使这不是最好的设计,为什么回调没有被触发?

【问题讨论】:

  • 仅供参考,如果视图当前不可见,MutableLiveData 不会更新值。确保这对您来说不是问题。如果我找到与上述观点相关的参考资料,我会附上一些参考资料。
  • 关于你的第一个问题:是的。 Flow 优于 LiveData 的主要优势在于它限制了对特定于 Android 的 API 的依赖,但如果你让它依赖于 LiveData,那就浪费了。可以使用 StateFlow 代替 LiveData。

标签: android kotlin android-livedata kotlin-coroutines coroutine


【解决方案1】:

首先,如果你使用的是androidx.lifecycle:lifecycle-livedata-ktx神器,你可以简单地使用liveData.asFlow()

如果您确实想使用callbackFlow 滚动自定义实现,则需要在流程构建器中调用awaitClose{...},否则将被视为立即完成。

override suspend fun currentUserFlow(): Flow<UserProfile?> =
        callbackFlow {
            val observer = Observer<UserProfile?>{
                offer(it)
            }
            userLiveData.observeForever(observer)
            awaitClose{
                // called when the flow is no longer collected, e.g. the collecting 
                // CoroutineScope has been cancelled
                userLiveData.removeObserver(observer)
            }
        }

【讨论】:

  • 谢谢你,这回答了我所有的问题。听起来我忘记了流并在实时数据上构建一切,当我需要使用它时,我只是将它作为流提供
猜你喜欢
  • 1970-01-01
  • 2018-09-22
  • 2016-11-04
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 2011-02-12
  • 2020-08-08
相关资源
最近更新 更多