I'm using a room database to run some heavy database operation. I am not using LiveData for this operation as I use the result for computation only. Now if in my main fragment I have this
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
val result = viewModel.someHeavyOperation() // a suspend fun
doSomething(result)
}
}
I get a Skipped xx frames! Your application might be doing to much work on main thread.
on startup which I don't get if I leave out the database query.
Now some answers here like this one or that one seem to suggest running the query on IO thread, like
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
withContext(Dispatchers.IO) {
val result = viewModel.someHeavyOperation() // a suspend fun
}
doSomething(result)
}
}
which does increase performance for me. What confuses me though is that in an article by the android developers publication on medium it says
Note: Room uses its own dispatcher to run queries on a background thread. Your code should not use withContext(Dispatchers.IO) to call suspending room queries. It will complicate the code and make your queries run slower.
However, they only seem to consider the case where the expensive bits are the ensuing calculations, where they seem to suggest something like
override fun onActivityCreated(savedInstanceState: Bundle?) {
lifecycleScope.launch {
val result = viewModel.someOperation() // a suspend fun
withContext(Dispatchers.Default) {
doSomethingHeavy(result)
}
}
}
So now my questions:
- Why should it matter from which dispatcher room queries are called if room uses a custom dispatcher anyways?
- How to perform expensive room queries without blocking the main thread?