Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

351
Visualizações
Room allowMainThreadQueries with Kotlin coroutines

The official Android documentation states that using allowMainThreadQueries() is not recommended because it could lock the UI for a long period of time and trigger an ANR. But Kotlin coroutines gave us the possibility to perform some operation in the main thread without effectively blocking the UI.

So I'm asking: is it safe to use allowMainThreadQueries() and access the database in a couroutine scope running on the main thread? Like in the following:

// WITH allowMainThreadQueries()
val activityJob = Job()
val mainScope = CoroutineScope(Dispatchers.Main + activityJob)
mainscope.launch {

    // access room database and retrieve some data

    // update UI with data retrived

}

Or we should stick to the old way of not allowing main thread queries and performing database queries in another thread?

// WITHOUT allowMainThreadQueries()
val activityJob = Job()
val defaultScope = CoroutineScope(Dispatchers.Default + activityJob)
val mainScope = CoroutineScope(Dispatchers.Main + activityJob)
defaultScope.launch {

    // access room database and retrieve some data

    mainScope.launch {
        // update UI with data retrived
    }

}

I'm asking because the former way (with allowMainThreadQueries()):

  • is much more readable (I can update the UI in the same coroutine context of the functions that access the database, without bearing about starting the UI updates in another coroutine scope)
  • allows for simpler error handling
  • makes use of only one coroutine scope (so less scopes to care about)
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

You shouldn't need allowMainThreadQueries() for this to work. A scoped coroutine executs in its thread.

This is what I did not long ago:

@UiThread
fun getUsers(context: Context): LiveData<List<User>> {
    if (!::users.isInitialized) {
        users = MutableLiveData()
        users.postValue(MyDatabase.get(context).users().getAll())
        GlobalScope.launch(Dispatchers.Main) {
            val usersFromDb: List<User> = async(Dispatchers.IO) {
                return@async MyDatabase.get(context).users().getAll()
            }.await()
            users.value = usersFromDb
        }
    }
    return users
}

You can see this getUsers() method gets called from main thread, returning a LiveData (which is handy in this case). The database query happens in GlobalScope.launch().

So yes, your design is one I personaly like. And one that works. But I don't think that you'll need allowMainThreadQueries() at all. Feel free to read (my) blog post: https://proandroiddev.com/android-viewmodel-livedata-coroutines-contraption-e1e44af690a6

over 4 years ago · Santiago Trujillo Relatório

0

It is recommended to access the database in your ViewModel inside viewmodelScope. If you are you need to access room database from activity or fragment use

lifecyclescope.launch{ // access database dao functions here which are suspend in definition. }

Or inside the lifecycleScope change your thread using withContext(Dispatchers.IO){}

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda