【发布时间】:2022-01-11 16:18:01
【问题描述】:
我有功能,它到达 API 并将接收到的对象放入数据库。然后此函数返回 Long 作为插入对象的 id。我想用协程在后台运行这个函数,仍然得到新插入对象的id。
但是在我在片段中运行函数后 LiveData 保持为空,并且仅在第二个按钮单击时获得正确的 id。
这是因为我无法从 cooutin 获得任何东西,或者只是请求和数据库插入需要时间,我必须等待“urlEntityId”更新?
这是来自 Fragment 的代码:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.etSearch.apply {
setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
val pattern = DOMAIN_VALIDATION
val url = this.text.toString()
if (url.matches(pattern)) {
viewModel.loadUrlModelFromApi(url)
val action =
SearchFragmentDirections.actionSearchFragmentToResultFragment(
viewModel.urlEntityId.value ?: 1L
)
navController?.navigate(action)
} else {
binding.textLayout.error = "Please enter correct domain name."
}
true
} else {
false
}
}
doOnTextChanged { text, start, before, count ->
binding.textLayout.error = null
}
}
}
还有我的 ViewModel 代码:
class SearchViewModel @Inject constructor(private val repository: UrlRepository) : ViewModel() {
private val _isLoading = MutableLiveData<Boolean>()
val isLoading: LiveData<Boolean> = _isLoading
private val _toastError = MutableLiveData<String>()
val toastError: LiveData<String> = _toastError
private val _urlEntity = MutableLiveData<UrlEntity>()
val urlEntity: LiveData<UrlEntity> = _urlEntity
private var _urlEntityId = MutableLiveData<Long>()
var urlEntityId: LiveData<Long> = _urlEntityId
fun loadUrlModelFromApi(domainName: String) {
_isLoading.postValue(true)
viewModelScope.launch(Dispatchers.IO) {
_urlEntityId.postValue(repository.getUrl(domainName))
}
_isLoading.postValue(false)
}}
【问题讨论】:
-
将
_isLoading.postValue(false)放入launch块中。launch立即返回,这就是为什么_isLoading值在repository.getUrl函数被调用之前更改为 false 的原因。此外,您不能在调用loadUrlModelFromApi后立即使用_urlEntityId。它还没有收到价值。您需要观察实时数据,然后进行导航。 -
是的,它成功了,谢谢!
标签: android kotlin mvvm kotlin-coroutines