Reputation: 571
I am getting this error while trying to display Room data in a LazyColumn in my project.
Cannot access database on the main thread since it may potentially lock the UI for a long period of time
I don't know why it is trying to access the database since I'm getting it with a ViewModelScope. Bellow is my MainActivity code and the ViewModel
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val viewModel: UserViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val users = viewModel.userList.value
LazyColumn(modifier = Modifier.fillMaxWidth()) {
items(users){data->
MyCard(data)
}
@HiltViewModel
class UserViewModel @Inject constructor(
private val repository: MainRepository
) : ViewModel() {
val userList: MutableState<List<User>> = mutableStateOf(listOf())
init {
viewModelScope.launch {
try {
val result: List<User> = repository.getAllUsers()
userList.value = result
} catch (e: Exception) {
Log.e("SSS", "${e.message.toString()}; ${e.stackTrace}")
}
}
}
Upvotes: 0
Views: 1042
Reputation: 1282
When launch { ... } is used without parameters, it inherits the context (and thus dispatcher) from the CoroutineScope it is being launched from.
Use IO thread to execute your code
viewModelScope.launch(Dispatchers.IO) {
try {
val result: List<User> = repository.getAllUsers()
userList.postValue(result)
} catch (e: Exception) {
Log.e("SSS", "${e.message.toString()}; ${e.stackTrace}")
}
}
Upvotes: 1
Reputation: 93511
Assuming you are following the pattern of your repository passing through functions from the DAO, you should mark this function in your DAO as a suspend
function. This will cause it to automatically use a background thread. Then mark your corresponding repository function suspend
so it can call the other suspend function.
Then in your coroutine, since getAllUsers()
is a proper suspend function that internally handles proper use of background threads, there is nothing more you need to change.
The reason it gives you the warning is that by default, the viewModelScope
runs on the main thread. It is up to you to wrap blocking calls in withContext(Dispatchers.IO)
to run them in a background thread. But if you use suspend
functions from the DAO, you don't have to worry about that because the function isn't blocking.
Upvotes: 1