Coroutines With Room Persistence Library
In this tutorial, you’ll learn how to use coroutines with the Room persistence library to allow for asynchronous database operations. By Kyle Jablonski.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Coroutines With Room Persistence Library
25 mins
- Getting Started
- Pre-Populating the Database
- Creating the RoomDatabase.Callback
- Exploring CoroutineScope
- Loading the Players in the Background
- Providing CoroutineScope
- Suspending Functions
- Observing Changes to Data
- Getting a Single Player
- Updating a Player
- Adding Update to the Dao
- Adding Update to the Repository
- Adding Update to the ViewModel
- Adding Update to the UI
- Deleting a Player
- Adding Delete to the DAO
- Adding Delete to the Repository
- Adding Delete to the ViewModel
- Adding Delete to the UI
- Where to Go From Here?
Updating a Player
To update a tennis player, use the same approach you took in the previous steps. There will again be a series of steps to complete the feature, but it won’t be so difficult this time. You already laid the groundwork after all.
Adding Update to the Dao
To begin, open the PlayerDoa.kt file and add the updatePlayer()
as shown below:
@Update
suspend fun updatePlayer(player: Player)
Here, you annotate with @Update
to tell Room that updatePlayer()
DAO method will perform update operations. The suspend
keyword in the method signature lets Room know this DAO method will suspend its execution.
Adding Update to the Repository
Next, open the PlayerRespository.kt file and add the following code:
suspend fun updatePlayer(player: Player) {
playerDao.updatePlayer(player)
}
Here you wrapped the DAO’s functionality to update a Player
with another suspension function.
Adding Update to the ViewModel
Time to update the DetailViewModel.kt file to run the repository’s updatePlayer(player: Player)
within a coroutine. First, add the following method to the end of DetailViewModel.kt file:
// 1
fun updatePlayer(player: Player) = viewModelScope.launch {
// 2
repository.updatePlayer(player)
}
- Here, you added a new method to update the
-
viewModelScope
to calllaunch
, a coroutine builder method - This, in turn, calls
updatePlayer(player: Player)
within a coroutine.
Player
. This method uses
Adding Update to the UI
Next up, you will setup the MenuItem
in the Toolbar
to update the selection of favorite player in the database. For simplicity, you will make changes only in the setupFavoriteToggle()
function.
Open the DetailsFragment.kt file and replace the TODO in setupFavoriteToggle(checkBox: CheckBox, player : Player)
with the following:
// 1
checkBox.setOnCheckedChangeListener { _, b ->
// 2
player.favorite = b
// 3
detailViewModel.updatePlayer(player)
}
// 4
checkBox.isChecked = player.favorite
Here you are:
- Attaching
OnCheckedChangeListener
to the checkbox starMenuItem
. - Assigning the player-favorite property to the checkbox checked value.
- Calling
updatePlayer(player)
from ViewModel. - Handling the initial value of
checkBox.isChecked
.
Now, you need to call this setupFavoriteToggle
method from the observer up in onViewCreated()
.
Add the call to setupFavoriteToggle
, just above displayPlayer()
in the observer definition as shown below:
detailViewModel.getPlayer(playerListItem).observe(this, Observer {
this.player = it
setupFavoriteToggle(checkbox, it) // called the method here
displayPlayer()
})
Here, you’re calling the method that sets up the checkbox toggle for favorites.
Great Job! Now when you navigate away from the DetailsFragment
you will see a filled-in star next to the Player
within the list and when you navigate back to DetailsFragment
the star menu item will highlight as well. Best of all, this is all happening by calling to update the player within the database using the DAO’s suspending function and the ViewModelScope
‘s launch method to run the operation in a coroutine.
Build and run the application to observe the new behavior. You can now favorite your favorite players.
Deleting a Player
Users may also want to remove players from the application. In this step, you’ll add a delete-player feature for just such an occasion.
Adding Delete to the DAO
To begin, open the PlayerDoa.kt file and add the deletePlayer()
method call:
@Delete
suspend fun deletePlayer(player: Player)
This should look familiar. You’ve added another suspending function to the DAO and provided @Delete
annotation so that Room knows this method will perform delete operations.
Adding Delete to the Repository
Now, it’s time to update the repository. Open the PlayerRepository.kt file and add the following code:
suspend fun deletePlayer(player: Player) {
playerDao.deletePlayer(player)
}
Here, you added another suspending function that uses PlayerDao
to call the deletePlayer()
method from the previous step.
Adding Delete to the ViewModel
You’ll have to update DetailsViewModel
again to call the deletePlayer()
method from repository
. Open the DetailsViewModel.kt file and add the following method:
// 1
fun deletePlayer(player: Player) = viewModelScope.launch {
// 2
repository.deletePlayer(player)
}
Here, you’re doing much the same as the update method call from the previous feature implementation. You use viewModelScope
to call launch
and run the operation in a coroutine.
Wow, you are becoming a pro at this!
Adding Delete to the UI
In this last step, you’ll add delete behavior to the UI. Open the DetailsFragment.kt file one more time and add the following code inside deleteCurrentPlayer()
replacing the TODO:
detailViewModel.deletePlayer(player)
dismiss()
Here, you invoked deletePlayer(player)
on the detailViewModel
and dismissed DetailsFragment
.
Build and run the application to observe the new behavior. You can now delete any players you’d like.
Where to Go From Here?
Great Job! You’re now a Suspension-Function-Room-Database-Storing Pro! If you had any difficulty following along, no worries. Just import the TennisPlayers-final version of the application and compare your code to it.
If you enjoyed working with LiveData, you may discover you enjoy the new Flow addition from the release of 2.2. For more information on Flow, check out the developer’s release notes.
If you’re looking for Room or Coroutine content, read Room DB: Advanced Data Persistence or Kotlin Coroutines Tutorial for Android: Advanced to learn more.
Thank you for reading! If you have any questions or comments, please join the forum discussion below!