从后台线程查询房间数据库
Room Database Query from background Thread
我读到在房间数据库中查询数据的一种方法是使用 Livedata,它可以在主线程上使用,因为它是异步的。
我想使用 LiveData 而不是 RxJava 或 AsyncTask。
为此,在我的存储库中 class 我有函数 getSomeData() ,其中 returns LiveData> 我在我的 viewModel 构造函数中调用了这个函数:
private var mObservableSomeData: LiveData<List<SomeData>>
init {
mObservableSomeData = repository.getSomeData()
}
fun getSomeData(): LiveData<List<SomeData>> {
return mObservableSomeData
}
然而它崩溃说:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
我该怎么办?
Room 不允许在主线程上进行数据库操作,除非您使用 allowMainThreadQueries()
.
允许在主线程上进行数据库操作
MyApp.database = Room.databaseBuilder(this,AppDatabase::class.java,"MyDatabase")
.allowMainThreadQueries()
.build()
正如@LieForBananas 所指出的,您很可能在插入时出错。每当你有 @Query 并且你正在将返回的数据包装到一个可观察的对象中时,例如LiveData 或 Flowable,您的查询默认在后台线程上执行。
请记住,Room 数据库确保返回可观察到的查询在后台线程上 运行。这就是为什么,如果你在 Flowable 中包装返回值,你不必在创建观察者时显式地写 .subscribeOn(Schedulers.io) 。而如果您使用 Flowable 进行网络调用(Single 可能更好,因为通常我们只需要发出一次),那么您必须显式地将 .subscribeOn(Scheduler.io()) 写入 运行 上的调用后台线程。
我读到在房间数据库中查询数据的一种方法是使用 Livedata,它可以在主线程上使用,因为它是异步的。
我想使用 LiveData 而不是 RxJava 或 AsyncTask。
为此,在我的存储库中 class 我有函数 getSomeData() ,其中 returns LiveData> 我在我的 viewModel 构造函数中调用了这个函数:
private var mObservableSomeData: LiveData<List<SomeData>>
init {
mObservableSomeData = repository.getSomeData()
}
fun getSomeData(): LiveData<List<SomeData>> {
return mObservableSomeData
}
然而它崩溃说:
Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
我该怎么办?
Room 不允许在主线程上进行数据库操作,除非您使用 allowMainThreadQueries()
.
MyApp.database = Room.databaseBuilder(this,AppDatabase::class.java,"MyDatabase")
.allowMainThreadQueries()
.build()
正如@LieForBananas 所指出的,您很可能在插入时出错。每当你有 @Query 并且你正在将返回的数据包装到一个可观察的对象中时,例如LiveData 或 Flowable,您的查询默认在后台线程上执行。
请记住,Room 数据库确保返回可观察到的查询在后台线程上 运行。这就是为什么,如果你在 Flowable 中包装返回值,你不必在创建观察者时显式地写 .subscribeOn(Schedulers.io) 。而如果您使用 Flowable 进行网络调用(Single 可能更好,因为通常我们只需要发出一次),那么您必须显式地将 .subscribeOn(Scheduler.io()) 写入 运行 上的调用后台线程。