Hi! Today I’ll tell you how to get data from Room database in reactive way.
Before starting make sure you have following in your build.gradel:
// Room components implementation "android.arch.persistence.room:runtime:$rootProject.roomVersion" implementation "android.arch.persistence.room:rxjava2:$rootProject.roomVersion" annotationProcessor "android.arch.persistence.room:compiler:$rootProject.roomVersion" androidTestImplementation "android.arch.persistence.room:testing:$rootProject.roomVersion" // Lifecycle components implementation "android.arch.lifecycle:extensions:$rootProject.archLifecycleVersion" implementation "android.arch.lifecycle:reactivestreams:$rootProject.archLifecycleVersion" annotationProcessor "android.arch.lifecycle:compiler:$rootProject.archLifecycleVersion" // Rx implementation 'io.reactivex.rxjava2:rxandroid:2.1.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.1'
First we need to get database from assets and define Dao class for data.
@Database(entities = {Verse.class}, version = 1, exportSchema = false) public abstract class MyRoomDatabase extends RoomDatabase { public abstract MyDataDao myDataDao(); private static MyRoomDatabase INSTANCE; static MyRoomDatabase getDatabase(final Context context) { if (INSTANCE == null) { synchronized (MyRoomDatabase.class) { if (INSTANCE == null) { INSTANCE = Room.databaseBuilder(context.getApplicationContext(), MyRoomDatabase.class, "data.sqlite3") // get db from assets .openHelperFactory(new AssetSQLiteOpenHelperFactory()) .build(); } } } return INSTANCE; } public void destroyInstance() { synchronized (MyRoomDatabase.class) { INSTANCE = null; } } } @Dao public interface MyDataDao { @Query("SELECT * from verses ORDER BY RANDOM() LIMIT 1") LiveData<Verse> getRandomVerse(); @Query("SELECT * from verses ORDER BY RANDOM() LIMIT 1") // same request Flowable<Verse> getRxRandomVerse(); }
Above code represents raw request for random Verse objects from database table verses
What I like about Room is it allows us to get Rx Flowable as well as LiveData objects out of the box!
In our case we will use Flowable.
Next, define a repository class:
class MyRepository(context: Context?) { private val mDataDao: MyDataDao private val db: MyRoomDatabase? = MyRoomDatabase.getDatabase(context) init { mDataDao = db!!.myDataDao() } fun getRxRandomVerse(): Flowable<Verse> { return mDataDao.getRxRandomVerse } fun getDb(context: Context?): MyRoomDatabase? { return db ?: MyRoomDatabase.getDatabase(context) } fun closeDb() { db?.close() } }
Finally, let’s extract data onto presentation layer:
class MainActivityPresenter { private var mRepository: MyRepository? = null fun attach(mainActivityView: MainActivityView, context: Context) { this.mainActivityView = mainActivityView this.mRepository = MyRepository(context) } fun getRandomVerse() { mainActivityView!!.showProgressBar() mRepository.getRxRandomVerse() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ verse -> mainActivityView!!.hideProgressBar() updateUI(verse?.toString()) }, { error -> mainActivityView!!.hideProgressBar() error.printStackTrace() }) } } class MainActivity : MainActivityPresenter.MainActivityView { ... override fun updateUI(verse: String) { textViewVerse.text = verse } ... }
That’s all in general. Pretty simple and handy. I’ve successfully implemented this code in a new random quote app
If you have any questions, leave in comments below.