使用 livedata 协程不会被执行
Using livedata coroutine doesn't gets executed
我正在使用 liveData 协程,如下所示。我的函数需要 3 个参数 - 访问数据库,进行 API 调用和 return 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
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())
函数没有被执行。有什么我错过的吗?
liveData {}
扩展函数returnsMediatorLiveData
的一个实例
liveData { .. emit(T) } // is a MediatorLiveData which needs a observer to execute
Why is the MediatorLiveData
addSource block not executed ?
我们需要始终观察一个MediatorLiveData
使用liveData观察器否则源块永远不会被执行
因此,要使 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)
创建了一个 new instance 的 mediator liveData,它没有任何观察者。观察到的旧实例被覆盖。您需要在单击按钮时再次观察 getImages(...)
的新实例。
images.observe(lifecycleOwner) { // on button click we observe again.
// your observer code goes here
}
见MediatorLiveData and
我正在使用 liveData 协程,如下所示。我的函数需要 3 个参数 - 访问数据库,进行 API 调用和 return 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
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())
函数没有被执行。有什么我错过的吗?
liveData {}
扩展函数returnsMediatorLiveData
liveData { .. emit(T) } // is a MediatorLiveData which needs a observer to execute
Why is the
MediatorLiveData
addSource block not executed ?
我们需要始终观察一个MediatorLiveData
使用liveData观察器否则源块永远不会被执行
因此,要使 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)
创建了一个 new instance 的 mediator liveData,它没有任何观察者。观察到的旧实例被覆盖。您需要在单击按钮时再次观察 getImages(...)
的新实例。
images.observe(lifecycleOwner) { // on button click we observe again.
// your observer code goes here
}
见MediatorLiveData and