gpt4 book ai didi

android - 将 viewModelScope 与 LiveData 一起使用时出现问题

转载 作者:行者123 更新时间:2023-12-04 15:06:10 24 4
gpt4 key购买 nike

我正在使用 viewModelScopeViewModel它调用存储库中的挂起函数,如下所示:

查看型号

class DeepFilterViewModel(val repo: DeepFilterRepository) : ViewModel() {

var deepFilterLiveData: LiveData<Result>? = null

fun onImageCompressed(compressedImage: File): LiveData<Result>? {
if (deepFilterLiveData == null) {
viewModelScope.launch {
deepFilterLiveData = repo.applyFilter(compressedImage)
}

}
return deepFilterLiveData
}
}

存储库
class DeepFilterRepository {

suspend fun applyFilter(compressedImage: File): LiveData<Result> {
val mutableLiveData = MutableLiveData<Result>()
mutableLiveData.value = Result.Loading

withContext(Dispatchers.IO) {
mutableLiveData.value = Result.Success("Done")

}
return mutableLiveData
}
}

我正在观察 fragment 中的 LiveData,如下所示:
 viewModel.onImageCompressed(compressedImage)?.observe(this, Observer { result ->
when (result) {

is Result.Loading -> {
loader.makeVisible()
}

is Result.Success<*> -> {
// Process result

}
}
})

问题是我没有从 LiveData 中获得任何值(value)。如果我不使用 viewModelScope.launch {}如下所示,那么一切正常。
class DeepFilterViewModel(val repo: DeepFilterRepository) : ViewModel() {

var deepFilterLiveData: LiveData<Result>? = null

fun onImageCompressed(compressedImage: File): LiveData<Result>? {
if (deepFilterLiveData == null) {
deepFilterLiveData = repo.applyFilter(compressedImage)
}
return deepFilterLiveData
}
}

我不知道我错过了什么。任何帮助将不胜感激。

最佳答案

这段代码:

viewModelScope.launch {
deepFilterLiveData = repo.applyFilter(compressedImage)
}

立即返回,所以当您第一次调用 onImageCompressed()您返回的方法 nulldeepFilterLiveData .因为在你的 UI 中你使用 ?.null onImageCompressed()的返回值 when条款将无法达成。没有协程的代码可以工作,因为在这种情况下你有顺序代码,你的 ViewModel 等待存储库调用。

为了解决这个问题,您可以保留 ViewModel-UI 交互的 LiveData 并直接从存储库方法返回值:
class DeepFilterRepository {

suspend fun applyFilter(compressedImage: File) = withContext(Dispatchers.IO) {
Result.Success("Done")
}

}

和 View 模型:
class DeepFilterViewModel(val repo: DeepFilterRepository) : ViewModel() {

private val _backingLiveData = MutableLiveData<Result>()
val deepFilterLiveData: LiveData<Result>
get() = _backingLiveData

fun onImageCompressed(compressedImage: File) {
// you could also set Loading as the initial state for _backingLiveData.value
_backingLiveData.value = Result.Loading
viewModelScope.launch {
_backingLiveData.value = repo.applyFilter(compressedImage)
}
}
}

关于android - 将 viewModelScope 与 LiveData 一起使用时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55932799/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com