Open In App

How to Use Room with LiveData?

Improve
Improve
Like Article
Like
Save
Share
Report

In previous articles, we discussed how to use the Room persistence library in Android applications and how Room works internally. We also talked about the various operations we can perform with the help of Room. One of them is using LiveData with Room. The room allows for the simple integration of LiveData. You only need to return LiveData from your DAO methods, and Room will take care of the rest.

LiveData Observable Queries

When running queries, you’ll frequently want your app’s UI to automatically update when the data changes. Use a return value of type LiveData in your query method description to accomplish this.

Kotlin




@Dao
interface Course {
    @Query("SELECT * FROM courses")
    fun getAllLiveData(): LiveData<List<Course>>
}


When the database is updated, Room generates all of the code required to update the LiveData. The generated code appears to be as follows:

Kotlin




@Override
public LiveData<List<GFG>> getAllLiveData() {
  final String _sql = "SELECT * FROM course";
  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
  return __db.getInvalidationTracker().createLiveData(new String[]{"course"}, false, new Callable<List<GFG>>() {
      
    @Override
    public List<GFG> call() throws Exception {
      final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
      try {
        final int _cursorIndexOfUid = CursorUtil.getColumnIndexOrThrow(_cursor, "uid");
        final int _cursorIndexOfFirstName = CursorUtil.getColumnIndexOrThrow(_cursor, "first_name");
        final int _cursorIndexOfLastName = CursorUtil.getColumnIndexOrThrow(_cursor, "last_name");
        final List<GFG> _result = new ArrayList<GFG>(_cursor.getCount());
        while(_cursor.moveToNext()) {
          final GFG _item;
          final int _tmpUid;
          _tmpUid = _cursor.getInt(_cursorIndexOfUid);
          final String _courseName;
          _courseName = _cursor.getString(_cursorIndexOfFirstName);
          final String _coursePrice;
          _coursePrice = _cursor.getString(_cursorIndexOfLastName);
          _item = new GFG(_tmpUid,_courseName,_coursePrice);
          _result.add(_item);    
        }
        return _result;
      } finally {
        _cursor.close();
      }
    }
  
    @Override
    protected void finalize() {
      _statement.release();
    }
  });
}


__db.getInvalidationTracker() is used in the preceding code (). createLiveData() accepts an array of tableNames, the inTransaction boolean flag, and a callable computeFunction.

GeekTip: RoomTrackingLiveData uses tableNames to monitor for changes.

  1. The inTransaction parameter specifies whether the query must be executed as a transaction or not.
  2. computeFunction is a callable that is invoked whenever the observed tables change.

We can also see that the call() method of computeFunction performs the actual query execution. It is called whenever an observer begins observing the LiveData or whenever any changes occur in the observed tables.

RxJava’s Room

In previous articles, we discussed how to use the Room persistence library in Android applications. We also talked about the various operations that Room DAOs can perform. Using Room, working with RxJava observables becomes a breeze. We need to include the following dependency in our build to return RxJava observables from your DAO methods.

First, gradle:

dependencies {
  def room_version = "2.2.5"
  implementation "androidx.room:room-runtime:$room_version"
  kapt "androidx.room:room-compiler:$room_version"
  // Geeks for Geeks RxJava support for Room
  implementation "androidx.room:room-rxjava2:$room_version"
}

Reactive queries with RxJava Room include the following support for RxJava2 type return values:

  1. @Query methods: Room accepts Publisher, Flowable, and Observable return values.
  2. @Insert, @Update, and @Delete methods: Return values of type Completable, <SingleT>, and <MaybeT> are supported in Room 2.1.0 and higher.

Kotlin




@Dao
interface GFGDao {
    
    @Query("SELECT * from courses where uid = :id LIMIT 1")
    fun loadGFGById(id: Int): Flowable<GFG>
  
    @Insert
    fun insertCourses(vararg courses: GFG): Completable
  
    @Delete
    fun deleteAllCourses(courses: List<GFG>): Single<Int>
    
}


The following are examples of how these methods are put into practice:

Kotlin




@Override
public Completable insertLargeNumberOfGFGs(final GFG... GFGs) {
  return Completable.fromCallable(new Callable<Void>() {
    @Override
    public Void call() throws Exception {
      __db.beginTransaction();
      try {
        __insertionAdapterOfGFG.insert(GFGs);
        __db.setTransactionSuccessful();
        return null;
      } finally {
        __db.endTransaction();
      }
    }
  });
}
  
@Override
public Single<Integer> deleteAllGFGs(final List<GFG> GFGs) {
  return Single.fromCallable(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
      int _total = 0;
      __db.beginTransaction();
      try {
        _total +=__deletionAdapterOfGFG.handleMultiple(GFGs);
        __db.setTransactionSuccessful();
        return _total;
      } finally {
        __db.endTransaction();
      }
    }
  });
}
  
@Override
public Flowable<GFG> loadGFGById(final int courseID) {
  final String _sql = "SELECT * from GFGs where uid = ? LIMIT 1";
  final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
  int _argIndex = 1;
  _statement.bindLong(_argIndex, courseID);
  return RxRoom.createFlowable(__db, false, new String[]{"GFGs"}, new Callable<GFG>() {
    @Override
    public GFG call() throws Exception {
      // Some exception Handling magic
    }
  
    @Override
    protected void finalize() {
      _statement.release();
    }
  });
}


We can see from the autogenerated code that Room creates Completable and Single using the fromCallable() operator. In the RxRoom. createFlowable, Room makes use of Flowable To make a Flowable, use create(). The code inside callable’s call() method is similar to the non-reactive implementation.

Kotlin Coroutines in a Room

In previous articles, we discussed the Room persistence library and the benefits of using it. One of the benefits of using Room is how easily it can be integrated with other libraries, such as Kotlin Coroutines. So let’s talk about how we can do it with the help of Room. First and foremost, we must add the following dependency for Kotlin coroutine support:

dependencies {
  def room_version = "2.2.5"

  implementation "androidx.room:room-runtime:$room_version"
  kapt "androidx.room:room-compiler:$room_version"  
  // Basic extension for Kotlin to make Room work
  implementation "androidx.room:room-ktx:$room_version"
}

Kotlin coroutines can be used to write async methods

You can use the suspend Kotlin keyword to make your DAO methods asynchronous using Kotlin coroutines. This prevents them from being executed on the main thread.

Kotlin




@Dao
interface GFGDao {
    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertGFG(vararg course: GFG)    @Update
    suspend fun updateGFG(vararg course: GFG)    @Delete
    suspend fun deleteGFG(vararg course: GFG)    @Query("SELECT * FROM course")
    suspend fun loadAllGFG(): Array<GFG>
}


All of the methods listed above are implemented by Room. The implementation of suspending functions is very similar to that of non-suspend functions.

Kotlin




@Override
public Object insertGFG(final Course[] GFG, final Continuation<? super Unit> p1) {
  return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
    @Override
    public Unit call() throws Exception {
      __db.beginTransaction();
      try {
        __insertionAdapterOfCourse.insert(GFG);
        __db.setTransactionSuccessful();
        return Unit.INSTANCE;
      } finally {
        __db.endTransaction();
      }
    }
  }, p1);
}


Conclusion

The only difference between the two implementations is that in the case of suspending functions, CoroutinesRoom.execute is in charge of stopping the execution flow. This is all about using Room with LiveData, RxJava, and Kotlin Coroutines. we hope you found this Geeks for geeks article intriguing.



Last Updated : 28 Jan, 2022
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads