CoroutinesAdd some suspense to your databaseFlorina MuntenescuBlockedUnblockFollowFollowingFeb 6Room 2.
1 (currently in alpha) adds support for Kotlin coroutines.
DAO methods can now be marked as suspending to ensure that they are not executed on the main thread.
By default, Room will use the Architecture Components I/O Executor as the Dispatcher to run SQL statements, but you can also supply your own Executor when building the RoomDatabase.
Read on to see how to use this, how it works under the hood and how to test this new functionality.
Add some suspense to your databaseTo use coroutines and Room in your app, update to Room 2.
1 and add the new dependency to your build.
gradle file:implementation "androidx.
room}"You’ll also need Kotlin 1.
0 and Coroutines 1.
0 or newer.
You can now update your DAO methods to use suspension functions:DAO with suspend methods@Transaction methods can also be suspending and they can call other suspending DAO functions:DAO with suspend transaction functionRoom treats suspending functions differently, based on whether they are called within a transaction or not:1.
In a transactionRoom doesn’t do any handling of the CoroutineContext on which the database statement is triggered.
It’s the responsibility of the caller of the function to make sure that this is not on a UI thread.
Since suspend functions can only be called from other suspend functions or from coroutines, make sure that the Dispatcher you’re using is not Dispatcher.
Main, rather Dispatchers.
IO or your own custom one.
Not in a transactionRoom makes sure that the database statement is triggered on the Architecture Components I/O Dispatcher.
This Dispatcher is created based on the same I/O Executor used to run LiveData work on a background thread.
Testing DAO suspension functionsTesting a DAO suspending function is no different from testing any other suspending function.
For example, to check that after inserting a user we are able to retrieve it, we wrap the test in a runBlocking block:Testing DAO suspend functionsUnder the hoodTo see what’s under the hood, let’s take a look at the DAO class implementation Room generates for a synchronous and for a suspending insert:Synchronous and suspending insert functionsFor the synchronous insert, the generated code starts a transaction, executes the insert, marks the transaction as successful and ends it.
The synchronous method will just execute the insert on whatever thread it’s called from.
Room synchronous insert generated implementationNow let’s see how adding the suspend modifier changes things: the generated code will make sure that your data gets inserted but also that this happens off of the UI thread.
The generated code passes a continuation and the data to be inserted.
The same logic from the synchronous insert method is used but within a Callable#call method.
Room suspending insert generated implementationThe interesting part though is the CoroutinesRoom.
execute function, since this is the one that handles the context switch, depending on whether the database is opened and we are in a transaction or not.
The database is opened and we are in a transactionHere we’re just triggering the call method — i.
the actual insertion of the user in the databaseCase 2.
We’re not in a transactionRoom makes sure that the work done in the Callable#call method is performed on a background thread by using the Architecture Components IO Executor.
execute implementationStart using Room and coroutines in your app, the database work is guaranteed to be run on a non-UI Dispatcher.
Mark your DAO method with the suspend modifier and call them from other suspend functions or coroutines!.