Disclaimer: The Coroutines support for Room persistence 2.1 added in alpha mode.

Kotlin Coroutines are expanding in the area of Android Architecture Component. Room 2.1 (SQLite Persistence Library) added the support for coroutines. Now you can add the suspend keyword to DAO class methods and ensures that they are not executed in the MainThread.

This article assumes you have a basic familiarity with Room Persistence and Kotlin Coroutines.

Add Dependencies

First, let’s add the latest Room dependency for coroutine support in the app-level build .gradle file and also you need to add the kotlin coroutines dependency.

apply plugin: 'kotlin-kapt' dependencies { // Kotlin coroutine dependencies implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.0-alpha' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.0-alpha' // Room architecture component dependencies implementation 'androidx.room:room-runtime:2.1.0-alpha06' kapt 'androidx.room:room-compiler:2.1.0-alpha06' implementation 'androidx.room:room-ktx:2.1.0-alpha06' }

Once you have added the dependencies hit the Sync and everything should be fine without any kind of gradle error.

Get Started

Next, add the suspend keyword modifier to your Dao class methods in order to use suspension.

@Dao interface TaskDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertTask(t: Task): Long @Query(value = "SELECT * FROM tasks") suspend fun tasks(): List<Task> @Update suspend fun updateTask(t: Task) @Delete suspend fun deleteTask(t: Task) }

Along with @Insert, @Update, and @Delete, the @Query annotation method also supports the suspend keyword. After adding the suspension, our Dao class methods can execute without blocking the current thread.

Testing the Task Insertion

Testing a Dao suspending method is not different from other function. Let’s see an example of it.

class MyViewModel(private val taskDao : TaskDao) : ViewModel() { fun insert(t : Task) = viewModelScope.launch { taskDao.insert(t) } }

The code above is pretty straight forward. If you’re a little bit familiar with kotlin coroutines then you probably heard of ” The suspend method can only be a call from another suspend block“. That’s why we’re calling the insert method of TaskDao inside the launch builder.

Note: Room doesn’t handle the CoroutineContext on which the Dao class method is executed. It is the responsibility of the caller to make sure that it is not executed in a MainThread.

Retrieving All Tasks

class MyViewModel(private val taskDao : TaskDao) : ViewModel() { private val _mTasks = MediatorLiveData<List<Task>>() val tasks : LiveData<List<Task>> = _mTasks // 1 fun allTasks() = viewModelScope.launch { // 2 _mTasks.postValue(taskDao.tasks()) // 3 } }

Going over the above code.

Not exposing the MediatorLiveData publically. We’ve declared tasks , which only available for reading the value. Creates a launch coroutine builder so that we can execute our suspend method inside it. Sending the result back to its observers.

@Transaction With Suspend Keyword

In the current release of Room persistence library, the @Transaction annotation is only applicable to non-abstract Dao methods.

@Dao abstract class TaskDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insertTask(t: Task): Long @Transaction open suspend fun updateTask(t : Task) { delete(t) insert(t) } @Delete suspend fun deleteTask(t: Task) }

I’ve created a simple To-do application with kotlin coroutine and Room Persistence. You can get the complete code from the GitHub.

Hopefully, this article helps you to understand how to add suspend on @Dao class methods. If you’ve any suggestions I’d love to hear them. Happy coding.

Thank you for using your precious time to read this article and being here…