Android 协程流的回调未触发

Android callback for a coroutine flow is not fired

我有一项服务,其中数据由 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. 我是不是把事情搞复杂了?感觉穿越了很多层 数据从一点到另一点?使用 a 真的有优势吗? 流到这里?感觉只使用 LiveData 就可以了 更简单,不需要在两者之间进行转换
  2. 即使这不是最好的设计,为什么没有触发回调?

首先,如果你使用的是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)
            }
        }