Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Room Database Query from background Thread

I have read that one of the ways to query data in room database is to use Livedata which can be used on the main thread as it is asynchronous.

I would like to use LiveData instead of RxJava or AsyncTask.

For this in my repository class I have function getSomeData() which returns LiveData> and I call this function in my viewModel constructor:

private var mObservableSomeData: LiveData<List<SomeData>>

init {
    mObservableSomeData = repository.getSomeData()
}

fun getSomeData(): LiveData<List<SomeData>> {
    return mObservableSomeData
}

However it crashes saying:

Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

What should I do?

like image 656
Ana Koridze Avatar asked May 03 '18 13:05

Ana Koridze


People also ask

How do I run room queries in background thread?

Whenever you have @Query and you are wrapping returned data into an observable e.g. LiveData or Flowable, your query gets executed on background thread by default. Remember that Room Database ensure that the query returning observable is run on background thread.

Is room database deprecated?

This field is deprecated.

Is room database an ORM?

The room is an ORM ( Object Relational Mapper ) for SQLite database in Android. It is part of the Architecture Components. The room makes using SQLite much easier for you by implementing annotations.


2 Answers

As pointed out by @LieForBananas, most probably you are getting error while doing insertion. Whenever you have @Query and you are wrapping returned data into an observable e.g. LiveData or Flowable, your query gets executed on background thread by default.

Remember that Room Database ensure that the query returning observable is run on background thread. This is why, if you are wrapping returned value in Flowable, you don't have to explicitly write .subscribeOn(Schedulers.io) while creating observer. Whereas If you are using Flowable for network call(Single might be better because usually we need to emit only once), then you have to explicitly write .subscribeOn(Scheduler.io()) to run the call on a background thread.

like image 163
Amit Vikram Singh Avatar answered Oct 14 '22 03:10

Amit Vikram Singh


Room doesn't allow database operation on the Main thread unless you allow database on the main thread with allowMainThreadQueries().

MyApp.database = Room.databaseBuilder(this,AppDatabase::class.java,"MyDatabase")
                     .allowMainThreadQueries()
                     .build()
like image 43
Meet Patel Avatar answered Oct 14 '22 02:10

Meet Patel