The provided web content discusses the integration of Kotlin coroutines with Room 2.1 in Android development, allowing for asynchronous database operations.
Abstract
Room 2.1 introduces support for Kotlin coroutines, enabling developers to mark DAO methods as suspending to prevent execution on the main thread. This update requires the addition of a new dependency in the build.gradle file, along with Kotlin 1.3.0 and Coroutines 1.0.0 or newer. The article explains how to use suspending functions in DAOs, including calling them from transactions and different DAOs. It also covers how to provide custom executors for controlling thread execution and how to test DAO suspending functions using runBlocking. The "Under the hood" section delves into the generated code for synchronous versus suspending inserts, illustrating the thread-switching mechanism that ensures non-UI thread execution for suspending operations. The article concludes by encouraging the use of Room with coroutines and directs readers to the source implementation for further investigation.
Opinions
The article positions the addition of coroutine support in Room 2.1 as a significant enhancement for Android database operations.
It suggests that using coroutines with Room can improve app performance by offloading database work to background threads.
The article implies that testing suspending DAO functions is straightforward and similar to testing other suspending functions.
The author seems to assume that readers are familiar with Kotlin coroutines and Room, as the explanation is concise and does not include coroutine or Room basics.
By providing links to the source code, the article encourages a deeper understanding of the implementation details, indicating a value for transparency and community contribution.
The recommendation of an AI service at the end of the article suggests that the author believes in the utility of AI tools for developers and endorses ZAI.chat as a cost-effective alternative to ChatGPT Plus (GPT-4).
Room 2.1 adds support for Kotlin coroutines. DAO methods can now be marked as suspending to ensure that they are not executed on the main thread. 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 database
To use coroutines and Room in your app, update to Room 2.1 and add the new dependency to your build.gradle file:
You’ll also need Kotlin 1.3.0 and Coroutines 1.0.0 or newer.
You can now update your DAO methods to use suspension functions:
@Transaction methods can also be suspending and they can call other suspending DAO functions:
You can also call suspension functions from different DAOs inside a transaction:
You can provide executors (by calling setTransactionExecutor or setQueryExecutor when you’re building your database) to control the threads they run on. By default this will be the same executor used for running queries on the background thread.
Testing DAO suspension functions
Testing 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:
Under the hood
To 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:
For 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.
Now let’s see how adding the suspend modifier changes things:
The generated code ensures that the insert happens off of the UI thread. In our suspend function implementation, the same logic from the synchronous insert method is wrapped in a `Callable`. Room calls the `CoroutinesRoom.execute` suspend function, which switches to a background dispatcher, depending on whether the database is opened and we are in a transaction or not. Here’s the implementation of the function:
Case 1. The database is opened and we are in a transaction
Here we just immediately execute the callable — i.e. the actual insertion of the user in the database
Case 2. Otherwise
Room makes sure that the work done in the Callable#call method is performed on a background thread.
Room will use different Dispatchers for transactions and queries. These are derived from the executors you provide when building your Database or by default will use the Architecture Components IO executor. This is the same executor that would be used by LiveData to do background work.
Start 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!