尝试使用mvvm和livedata,我在数据库Room中有一个查询
@Query("SELECT * FROM User ")
fun getAllUsers(): LiveData<MutableList<User>>
@Query("SELECT * FROM User ")
fun getAllUsersRx(): Flowable<MutableList<User>>
我从ViewModel调用方法,两种情况都出现,但是如果一切都通过rx在另一个线程中工作,那么在LiveData情况下,一切都应该发生在mainThread中。但是,为什么Room不给出错误IllegalStateException:无法访问主线程上的数据库?在这种情况下使用LiveData直接向Room请求数据是否正确,还是我需要自己将操作转移到另一个线程?
答案 0 :(得分:0)
然后,对于LiveData,一切都应发生在mainThread中。
您在主线程上观察到它并在主线程上接收到查询的项目,但是查询本身是在ArchTasksExecutors.ioThread()
执行程序(后台线程)上执行的。
但是为什么Room不给出错误IllegalStateException:无法访问主线程上的数据库?
因为查询是在后台线程上执行的,所以当提取任务完成时,该查询会通过liveData.postValue(queriedData)
传递给UI线程。
在这种情况下使用LiveData直接向Room请求数据是否正确,还是我需要自己将操作转移到另一个线程?
LiveData自动处理“在后台线程上查询,并将结果传递给您的UI线程”。您可以检入生成的代码,这是怎么发生的,但是从技术上讲,Room已经为您完成了此操作。
您不需要Rx来让Room在后台线程上运行其查询,仅使用LiveData就足够了。
答案 1 :(得分:-1)
然后,对于LiveData,一切都应在mainThread中发生
您可以允许您的“数据库”构建器中的.allowMainThreadQueries()
在mainThread上运行。
但是为什么Room不给出错误IllegalStateException:无法 在主线程上访问数据库?
因为使用room-rxjava2
时,它可以处理所有线程。
我需要自己将操作转移到另一个线程吗?
您应该使用SubscribeOn(...)
关键字 EXPLICITLY 指定要处理请求的线程。
此[subscribeOn]仅影响Observable为 已订阅,它将留在下游。 source
...
.getAllUsersRx()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulars.mainThread)
.subscribe(...)