In the code snippet below, how to get the value of isValid
after viewModelScope.launch
is finished.
viewModelScope.launch
runs at last, inside fun checkCode()
. So fun checkCode()
is always return false.
fun someListener() {
if (checkCode() == true) {
//do something
}
}
fun checkCode(): Boolean {
var isValid = false
viewModelScope.launch(Dispatchers.Main) {
val response = withContext(Dispatchers.IO) {
// something do in background
}
if (response == "someString") {
isValid = true
// tried to type "return isValid" but syntax error
}
}
// the problem is below statements run before viewModelScope.launch
if (isValid) return true
else return false
}
suspend
function runs on background thread. To get the result from that function instead of using return
use LiveData
.
private val _isValid = MutableLiveData<Boolean>()
val isValid: LiveData<Boolean> // To observe the value outside the ViewModel class.
get() = _isValid
...
suspend fun doBackgroundWork() {
...
_isValid.postValue(true)
...
}
Now you can update the private value in the background thread and also observe this in the view controller (Fragment/Activity)
, do appropriate operations when you get the updated value.
Few different ways to use liveData from Documentation
viewModelScope.launch
will always return a Job
. So you can't really return a value from it. To gain what you want you can change your code style like below:
fun someListener() {
viewModelScope.launch {
if (checkCode() == true) {
//do something
}
}
}
suspend fun checkCode(): Boolean {
var isValid = false
val response = withContext(Dispatchers.IO) {
// something do in background
}
if (response == "someString") {
isValid = true
}
return isValid
}
Make the function a suspend function and run the entire thing in the coroutine, including the function and its return. Since you can't block the main thread while waiting for the coroutine to finish, you need to make it a suspend function so that it can suspend without blocking.
Your end result would look something like this:
fun someListener() {
viewModelScope.launch(Dispatchers.Main) {
if (checkCode() == true) {
//do something
}
}
}
suspend fun checkCode(): Boolean {
val response = withContext(Dispatchers.IO) {
// something in background
}
if (response == "someString") {
return true
}
return false
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.