为什么房间Livedata不返回值?

发布于 2025-02-08 12:31:14 字数 3008 浏览 2 评论 0原文

我对返回livedata的房间有问题。

我创建dao,并使用功能返回数据列表。我想返回为livedata。但是,它无法正常工作。

dao函数

@Transaction
@Query("SELECT * FROM AllocationPercentage WHERE id IN (:ids)")
fun getByIds(ids: List<Long>): LiveData<List<AllocationPercentageWithDetails>>

这是我在ViewModel中观察它的方式:

class AllocationViewModel(
    private val getAllocationByIdUseCase: GetAllocationByIdUseCase,
    private val getDetailByIdUseCase: GetAllocationPercentageByIdUseCase
) : ViewModel() {

    var allocationUiState: LiveData<AllocationUiState> = MutableLiveData()
        private set

    var allocationPercentageUiState: LiveData<List<AllocationPercentageUiState>> = MutableLiveData()
        private set

    val mediatorLiveData = MediatorLiveData<List<AllocationPercentageUiState>>()

    fun getAllocationById(allocationId: Long) = viewModelScope.launch(Dispatchers.IO) {
        val result = getAllocationByIdUseCase(allocationId) // LiveData

        allocationUiState = Transformations.map(result) {
            AllocationUiState(allocation = it.allocation)
        }

        mediatorLiveData.addSource(result) { allocation ->
            Log.d(TAG, "> getAllocationById")
            val ids = allocation.percentages.map { percentage -> percentage.id }
            val detailResult: LiveData<List<AllocationPercentageWithDetails>> =
                getDetailByIdUseCase(ids) // LiveData
            allocationPercentageUiState = Transformations.map(detailResult) { details ->
                Log.d(TAG, ">> Transform : $details")
                details.map {
                    AllocationPercentageUiState(
                        id = it.allocationPercentage.id,
                        percentage = it.allocationPercentage.percentage,
                        description = it.allocationPercentage.description,
                        currentProgress = it.allocationPercentage.currentProgress
                    )
                }
            }
        }
    }
}

AllocationPercentAgeUistate通过fragment观察到。

    Log.d(TAG, "observeViewModel: ${it?.size}")
    val percentages = it ?: return@observe
    setAllocationPercentages(percentages) // update UI
}

allocationViewModel.mediatorLiveData.observe(viewLifecycleOwner) {}

getDetailbyIdUsecase只是一个直接返回DAO结果的函数。

class GetAllocationPercentageByIdUseCase(private val repository: AllocationPercentageRepository) {
    operator fun invoke(ids: List<Long>): LiveData<List<AllocationPercentageWithDetails>> {
        return repository.getAllocationPercentageByIds(ids)
    }
}

知道为什么吗?谢谢。

I have a problem with Room that return LiveData.

I create Dao with function to returns list of data. I suppose to return as LiveData. But, it doesn't work as expected.

Dao function

@Transaction
@Query("SELECT * FROM AllocationPercentage WHERE id IN (:ids)")
fun getByIds(ids: List<Long>): LiveData<List<AllocationPercentageWithDetails>>

Here is how I observe it inside the ViewModel:

class AllocationViewModel(
    private val getAllocationByIdUseCase: GetAllocationByIdUseCase,
    private val getDetailByIdUseCase: GetAllocationPercentageByIdUseCase
) : ViewModel() {

    var allocationUiState: LiveData<AllocationUiState> = MutableLiveData()
        private set

    var allocationPercentageUiState: LiveData<List<AllocationPercentageUiState>> = MutableLiveData()
        private set

    val mediatorLiveData = MediatorLiveData<List<AllocationPercentageUiState>>()

    fun getAllocationById(allocationId: Long) = viewModelScope.launch(Dispatchers.IO) {
        val result = getAllocationByIdUseCase(allocationId) // LiveData

        allocationUiState = Transformations.map(result) {
            AllocationUiState(allocation = it.allocation)
        }

        mediatorLiveData.addSource(result) { allocation ->
            Log.d(TAG, "> getAllocationById")
            val ids = allocation.percentages.map { percentage -> percentage.id }
            val detailResult: LiveData<List<AllocationPercentageWithDetails>> =
                getDetailByIdUseCase(ids) // LiveData
            allocationPercentageUiState = Transformations.map(detailResult) { details ->
                Log.d(TAG, ">> Transform : $details")
                details.map {
                    AllocationPercentageUiState(
                        id = it.allocationPercentage.id,
                        percentage = it.allocationPercentage.percentage,
                        description = it.allocationPercentage.description,
                        currentProgress = it.allocationPercentage.currentProgress
                    )
                }
            }
        }
    }
}

The allocationPercentageUiState is observed by Fragment.

    Log.d(TAG, "observeViewModel: ${it?.size}")
    val percentages = it ?: return@observe
    setAllocationPercentages(percentages) // update UI
}

allocationViewModel.mediatorLiveData.observe(viewLifecycleOwner) {}

And getDetailByIdUseCase just a function which directly return result from Dao.

class GetAllocationPercentageByIdUseCase(private val repository: AllocationPercentageRepository) {
    operator fun invoke(ids: List<Long>): LiveData<List<AllocationPercentageWithDetails>> {
        return repository.getAllocationPercentageByIds(ids)
    }
}

Any idea why? Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-残月青衣踏尘吟 2025-02-15 12:31:14

var与livedata或mutableLivedata结合在一起是没有意义的。它打败了使用Livedata的目的。如果出现某些东西并观察您在该物业中拥有的原始Livedata,它将永远不会收到任何东西。它将无法知道有一个新的livedata实例应该观察到。

我无法确切地告诉您如何修复它,因为您上面的代码不完整,因此我无法分辨您在映射功能中要做什么,或者是否在某些函数中与在ViewModel初始化过程中进行调用。

Combining var with LiveData or MutableLiveData doesn't make sense. It defeats the purpose of using LiveData. If something comes along and observes the original LiveData that you have in that property, it will never receive anything. It will have no way of knowing there's a new LiveData instance it should be observing instead.

I can't exactly tell you how to fix it because your code above is incomplete, so I can't tell what you're trying to do in your mapping function, or whether it is called in some function vs. during ViewModel initialization.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文