Issue
I have the following function in my ViewModel:
fun insertMovie(movie: Movie): Long {
var movieId = 0L
viewModelScope.launch {
movieId = repository.insertMovie(movie)
Log.i(LOG_TAG, "add movie with id $movieId within launch")
}
Log.i(LOG_TAG, "add movieId with id $movieId")
return movieId
}
Then the following in the Dao:
@Suppress("RedundantSuspendModifier")
@WorkerThread
suspend fun insertMovie(movie: Movie): Long {
return movieDao.insert(movie)
}
In my activity I am doing the following:
viewModel.viewModelScope.launch {
val movieId = viewModel.insertMovie(Movie(...))
The movieId is always 0. Above I have two logs, the one within the launch{}
shows the right id, but the other shows 0. I don't know how to force the code in my activity to wait until the method completes.
Solution
A launch statement just launches a coroutine. What happens inside the coroutine does not matter to the rest of the function, thats why the code after the launch statement gets executet immediately after the launch and will probably be done before your repository.insertMovie()
.
As broot already mentioned, you could make the whole insertMovie()
function of your viewmodel suspend and launch a coroutine from your activity/fragment.
Another way would be to have some kind of flow or liveData that gets updated when your coroutine is done and let your view react to that. Here is a link to the documentation for StateFlow and SharedFlow: https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
Answered By - Tobias
Answer Checked By - Mary Flores (JavaFixing Volunteer)