如何结合 livedata 和 kotlin flow

Abh*_* AN 3 android kotlin android-livedata kotlin-coroutines kotlin-flow

把最新的collect放在observe里面好不好?

viewModel.fetchUserProfileLocal(PreferencesManager(requireContext()).userName!!)
            .observe(viewLifecycleOwner) {
                if (it != null) {
                    viewLifecycleOwner.lifecycleScope.launch {
                        viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
                            launch {
                                viewModel.referralDetailsResponse.collect { referralResponseState ->
                                    when (referralResponseState) {
                                        State.Empty -> {
                                        }
                                        is State.Failed -> {
                                            Timber.e("${referralResponseState.message}")
                                        }
                                        State.Loading -> {
                                            Timber.i("LOADING")
                                        }
                                        is State.Success<*> -> {
                                            // ACCESS LIVEDATA RESULT HERE??
}}}}
Run Code Online (Sandbox Code Playgroud)

我确信不是,当本地数据库发生变化时,我的 API 也会被调用三次,正确的方法是什么?

我的 ViewModel 看起来像这样,我从本地 Room DB 获取用户信息,推荐详细信息响应是 API 响应

private val _referralDetailsResponse = Channel<State>(Channel.BUFFERED)
val referralDetailsResponse = _referralDetailsResponse.receiveAsFlow()

init {
        val inviteSlug: String? = savedStateHandle["inviteSlug"]
        // Fire invite link
        if (inviteSlug != null) {
            referralDetail(inviteSlug)
        }
    }

fun referralDetail(referral: String?) = viewModelScope.launch {
        _referralDetailsResponse.send(State.Loading)
        when (
            val response =
                groupsRepositoryImpl.referralDetails(referral)
        ) {
            is ResultWrapper.GenericError -> {
                _referralDetailsResponse.send(State.Failed(response.error?.error))
            }
            ResultWrapper.NetworkError -> {
                _referralDetailsResponse.send(State.Failed("Network Error"))
            }
            is ResultWrapper.Success<*> -> {
                _referralDetailsResponse.send(State.Success(response.value))
            }
        }
    }

fun fetchUserProfileLocal(username: String) =
        userRepository.getUserLocal(username).asLiveData()

Run Code Online (Sandbox Code Playgroud)

Ser*_*gey 6

您可以将两个数据流合并为一个流并使用它们的结果。例如,我们可以使用扩展函数转换LiveData为,并且两个流程:FlowLiveData.asFlow()combine

combine(
  viewModel.fetchUserProfileLocal(PreferencesManager(requireContext()).userName!!).asFlow(),
  viewModel.referralDetailsResponse
) { userProfile, referralResponseState  ->
  ...
}.launchIn(viewLifecycleOwner.lifecycleScope)
Run Code Online (Sandbox Code Playgroud)

但最好将组合逻辑转移到ViewModel课堂上并观察总体结果。

使用LiveData.asFlow()扩展函数的依赖:

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
Run Code Online (Sandbox Code Playgroud)