Fetch data from Room Asynchronously with Coroutine(Flow) and Update UI With LiveData, Observe data change in Database In Android (Kotlin)
We can insert, update data into room database asynchronously with coroutine by calling suspend insert method we write inside DAO with below block
coroutineScope.launch{ // call suspended insert method here}
But we can not get data asynchronously with this approach. Fetching data is also long running operation but as we want the result back from it on UI thread and we want to observe database change for that Android hasn't provided any callback to coroutine.launch{} block
Our objective is, We want to fetch data from room database and always observe the result for any change database while lifecycleOwner is alive. (lifecycleOwner is the activity/fragment where we are observe database change). And process of fetching data should be on IO thread that keeps Main thread free to do UI work. and pass result back on main UI thread so that we can use result to update UI like notify recyclerview.
So , This can be possible with Flow combine with LiveData in Room Database when you are not using RxJava.
In DAO
@Query("SELECT * FROM grocery")
fun getAll(): Flow<List<Grocery>>
In Repository class
lateinit var groceries: Flow<List<Grocery>>init {
val db = GroceryManagementDb.getDatabase(application)
groceryDao = db!!.groceryDao()
groceries = groceryDao.getAll()
}
In ViewModel
we now convert Flow to LiveData
val groceries: LiveData<List<Grocery>> = groceryRepository.groceries.asLiveData()
In Fragment
model.groceries.observe(viewLifecycleOwner, Observer { groceries ->
Log.i("TAG", " Coroutine groceries size ${groceries.size}")
// You can notify adapter here
})
This observe block receives callback for data change in database like if any insert operation is happens while you are watching list of data. And we can do other operations like insert, update, delete with suspend , coroutine.launch{}
below is the reference link
https://github.com/googlecodelabs/android-room-with-a-view/tree/kotlin