I have a login app which uses Navigation Activity, JetPack and RoomDB. It has LoginFragment, LoginVieweModel, LoginDatabase, LoginDao and login Repository. I don't know the correct syntax to get UserCount from RoomDB.
The whole app is located in GitHub at https://github.com/msyusuf/LoginFragNavActivity.git.
Code in LoginDao is
@Query("SELECT COUNT(*) FROM loggedin_user_table")
suspend fun getLoggedInUserCount(): Int
Code in LoginViewModel is
fun getUserCount(): Int {
var count: Int = 99
viewModelScope.launch {
count = loginRepository.getUserCount()
Log.i(LOG_TAG, "In LoginViewModel.getUserCount(): count = $count")
}
return count
}
The fun getUserCount() does not have count from repository, it 99 which I used to initialize the count variable.
CodePudding user response:
In getUserCount()
function of LoginViewModel
class a coroutine, launched using launch
builder, will be executed after the function returns. You should think about how you want to use the data. If you want it to be used just as an input data for some another calculations then it make sense to make the getUserCount()
function suspend
:
suspend fun getUserCount(): Int {
val count: Int = loginRepository.getUserCount()
Log.i(LOG_TAG, "In LoginViewModel.getUserCount(): count = $count")
return count
}
If you want it to be displayed in UI you can make it suspend
like above and call it in a coroutine using lifecycleScope
:
in Activity
/Fragment
lifecycleScope.launch {
val count = viewModel.getUserCount()
// update UI
}
Another alternative is to apply reactive approach using LiveData
or Kotlin Flow
CodePudding user response:
You can return values from coroutine scope using withContext here read the documentation -> https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/with-context.html
you can change the function like this
suspend fun getUserCount(): Int {
return withContext(Dispatchers.IO) {
val count = loginRepository.getUserCount()
Log.i(LOG_TAG, "In LoginViewModel.getUserCount(): count = $count")
count
}
}