【问题标题】:Using livedata coroutine doesn't gets executed使用 livedata 协程不会被执行
【发布时间】:2021-05-12 08:51:41
【问题描述】:

我正在使用 liveData 协程如下。我的函数需要 3 个参数 - 访问数据库、进行 API 调用并返回 API 结果

fun <T, A> performGetOperation(
databaseQuery: () -> LiveData<T>,
networkCall: suspend () -> Resource<A>,
saveCallResult: suspend (A) -> Unit
): LiveData<Resource<T>> =
liveData(Dispatchers.IO) {
    emit(Resource.loading())
    val source = databaseQuery.invoke().map { Resource.success(it) }
    emitSource(source)

    val responseStatus = networkCall.invoke()
    if (responseStatus.status == SUCCESS) {
        saveCallResult(responseStatus.data!!)
    } else if (responseStatus.status == ERROR) {
        emit(Resource.error(responseStatus.message!!))
        emitSource(source)
    }
}

我将函数调用为

fun getImages(term: String) = performGetOperation(
    databaseQuery = {
        localDataSource.getAllImages(term) },
    networkCall = {
        remoteDataSource.getImages(term) },
    saveCallResult = {
        val searchedImages = mutableListOf<Images>()
        it.query.pages.values.filter {
            it.thumbnail != null
        }.map {
            searchedImages.add(Images(it.pageid, it.thumbnail!!.source, term))
        }
        localDataSource.insertAll(searchedImages)
    }
)

这是我的视图模型类

class ImagesViewModel @Inject constructor(
private val repository: WikiImageRepository
 ) : ViewModel() {

var images: LiveData<Resource<List<Images>>> = MutableLiveData()

fun fetchImages(search: String) {
    images = repository.getImages(search)
}
}

从我的片段中我正在观察变量

viewModel.images?.observe(viewLifecycleOwner, Observer {
        when (it.status) {
            Resource.Status.SUCCESS -> {
                println(it)
            }
            Resource.Status.ERROR ->
                Toast.makeText(requireContext(), it.message, Toast.LENGTH_SHORT).show()

            Resource.Status.LOADING ->
                println("loading")

        }
    })

我必须在点击按钮viewModel.fetchImages(binding.searchEt.text.toString())时获取新数据

函数没有被执行。有什么我错过了吗?

【问题讨论】:

    标签: android kotlin android-livedata kotlin-coroutines


    【解决方案1】:

    liveData {} 扩展函数返回一个MediatorLiveData 的实例

    liveData { .. emit(T) } // is a MediatorLiveData which needs a observer to execute
    

    为什么MediatorLiveData addSource 块没有被执行?

    我们需要始终观察使用 liveData 观察者的MediatorLiveData,否则源代码块永远不会执行

    所以要让 liveData 块执行,只需观察 liveData,

    performGetOperation(
        databaseQuery = {
            localDataSource.getAllImages(term) },
        networkCall = {
            remoteDataSource.getImages(term) },
        saveCallResult = {
            localDataSource.insertAll(it)
        }
    ).observe(lifecyleOwner) { // observing the MediatorLiveData is necessary
    }
    

    每次打电话时都是你的情况

    images = repository.getImages(search)
    

    一个 新实例 的中介 liveData 被创建,它没有任何观察者。观察到的旧实例被覆盖。您需要在单击按钮时再次观察 getImages(...) 的新实例。

    images.observe(lifecycleOwner) { // on button click we observe again.
         // your observer code goes here
    }
    

    MediatorLiveDatathis

    【讨论】:

    • 我在我的片段中观察它,我必须在按钮单击时获取新数据。仍然没有执行该功能,我已经更新了问题。你能看一下吗?
    • 但你从不观察需要观察者的perforGetOperation(...)。我们需要至少用一个空白观察者观察perforGetOperation(...) 以使其执行,正如我在答案@WIHY 中所显示的那样
    • 我从 getImages 观察到这很有趣
    • 按钮点击你需要再次观察,它现在是一个单独的实例@WISY它每次都会创建一个新实例
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 2021-05-17
    • 2022-08-18
    相关资源
    最近更新 更多