Using Room with LiveData and other third-party libraries
Note: This article is part of the advanced Room series which covers all the details about the Room persistence library. You can read all the articles here:
- Introduction to Room Persistent Library in Android
- Data Access Objects — DAO in Room
- Entity Relationship in Room
- How does Room work internally?
- Room Database Migrations
- Using Room with LiveData and other third-party libraries [You are here]
Room + LiveData
In the previous articles, we have discussed how we can use Room persistence library in our Android applications and how Room internally works. Also, we discussed about the different kind of operations we can do easily with the help of Room. Using LiveData with Room is also one of them.
Room supports integration of LiveData very easily. You just need to return LiveData from your DAO methods and Room takes care of everything else for you.
Observable queries with LiveData
When performing queries, you’ll often want your app’s UI to update automatically when the data changes. To achieve this, use a return value of type LiveData
in your query method description.
Room generates all necessary code to update the LiveData
when the database is updated. The generated code looks like this:
In the above code, __db.getInvalidationTracker().createLiveData()
takes tableNames
array, inTransaction
boolean flag and computeFunction
callable.
tableNames
is used for byRoomTrackingLiveData
to observe for changes.inTransaction
indicates whether the query has to be performed as a transaction or not.computeFunction
is a callable which is called whenever there are any changes in observed tables.
We can also see that the call()
method of computeFunction
does the actual execution of our query. It’s invoked when an observer starts observing the LiveData or whenever any changes happen in observed tables.
Room + RxJava
In the previous articles, we have discussed about using Room persistence library in our Android applications. We also discussed about the various operations we can perform using Room DAOs. Working with RxJava observables also becomes very easy using Room.
For returning RxJava observables from your DAO methods, we need to add the following dependency in our build.gradle
first:
dependencies {
def room_version = "2.2.5" implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" // RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
}
Reactive queries with RxJava
Room provides the following support for return values of RxJava2 types:
@Query
methods: Room supports return values of typePublisher
,Flowable
, andObservable
.@Insert
,@Update
, and@Delete
methods: Room 2.1.0 and higher supports return values of typeCompletable
,Single<T>
, andMaybe<T>
.
Implementation of these methods look like the following:
From the autogenerated code, we can see that Room is using the fromCallable()
operator to create Completable
and Single
. In RxRoom.createFlowable
, Room uses Flowable.create()
to create Flowable
.
Code inside call()
method of callable is similar to the non-reactive implementation.
Room + Kotlin Coroutines
In the previous articles, we have discussed about the Room persistence library and the advantages of using Room. One of the advantages of using Room is how easily we can integrate it with other libraries like Kotlin Coroutines. So let’s discuss how can we achieve it with the help of Room.
First of all, we need to add the following dependency for kotlin coroutines support:
dependencies {
def room_version = "2.2.5" implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"// Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
}
Write async methods with Kotlin coroutines
You can add the suspend
Kotlin keyword to your DAO methods to make them asynchronous using Kotlin coroutines functionality. This ensures that they cannot be executed on the main thread.
Room generates the implementation of all the above methods. Implementation of suspend
functions is very similar to non-suspend ones.
Here, CoroutinesRoom.execute
executes the passed callable asynchronously. Implementation of CoroutinesRoom.execute
is not available.
Non suspend function looks like the following:
The only difference between both implementations is that in case of suspend
functions, CoroutinesRoom.execute
is responsible for suspending the execution flow.
Thank You!!!