2

I get this error: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. It happens when I launch fun turnAllWordsOn() in the ViewModel (code below). This function launches coroutine, and I thought that coroutine always works on the backgroung thread. So why I get this error? Apprecieate any help

In Fragment:

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.action_turn_all_words_on -> {
            viewModel.turnAllWordsOn()
            true
        }
    // othes items
    }

In ViewModel:

fun turnAllWordsOn() = viewModelScope.launch {
    wordDao.turnAllWordsOn()
}

In Dao:

@Query("UPDATE word_table SET shown = 1")
fun turnAllWordsOn()
Alex Rodionow
  • 247
  • 3
  • 13

3 Answers3

6

You have to mark your Dao function as a suspend function if you want Room to run it on a background thread. Otherwise all you're doing is calling a synchronous function from a coroutine scope.

@Query("UPDATE word_table SET shown = 1")
suspend fun turnAllWordsOn()

As a side note, suspend functions don't automatically run on a background thread, however Room does the necessary work behind the scenes when you mark a query as suspend.

Henry Twist
  • 5,666
  • 3
  • 19
  • 44
2

Even if you have the answer, I still want to give some solution and cause of the problem, Performing networking, or accessing the database can block Ui Thread, so you can use

  1. Using RxJava:

    Completable.fromAction { wordDao.turnAllWordsOn() }

  2. Using Coroutine:

    @Query("UPDATE word_table SET shown = 1") suspend fun turnAllWordsOn()

LuongXuanNam
  • 67
  • 1
  • 4
1

Just a note for anyone who ends up here the accepted answer is correct, however if you are calling a Dao function from an activity you must put in inside a Coroutine scope. So after you add suspend onto your Dao function call it from the activity like this.

lifecycleScope.launch(Dispatchers.IO){
    // call Dao function here
}
JustSightseeing
  • 1,460
  • 3
  • 17
  • 37
Cainan Lay
  • 11
  • 1