从我读过的内容 Room不允许您在主线程上发出数据库查询(因为可能导致主线程延迟)。所以想象一下我想要更新textview在UI主线程上哪些数据我将如何获得回调。让我举个例子。想象一下,我想将我的业务模型数据存储到一个名为Events的对象中。因此我们有一个EventDao对象:
想象一下我们在下面有这个DAO对象:
@Dao
public interface EventDao {
@Query("SELECT * FROM " + Event.TABLE_NAME + " WHERE " + Event.DATE_FIELD + " > :minDate" limit 1)
LiveData<List<Event>> getEvent(LocalDateTime minDate);
@Insert(onConflict = REPLACE)
void addEvent(Event event);
@Delete
void deleteEvent(Event event);
@Update(onConflict = REPLACE)
void updateEvent(Event event);
}
现在在一些活动中我有一个textview,我想更新它的值,所以我这样做:
myTextView.setText(EventDao.getEvent(someDate));/*i think this is illegal as im trying to call room dao on mainthread, therefore how is this done correctly ? would i need to show a spinner while it updates ?*/
因为提取是从主线程发生的,我不认为我可以像这样调用它并期望平滑更新。什么是最好的方法?
更多信息:我想使用会议室数据库作为检索模型信息的机制,而不是将其静态保存在内存中。因此,通过休息服务下载后,我可以通过数据库在本地使用该模型。
更新:所以既然我正在返回一个liveata,那么我可以这样做:
eventDao = eventDatabase.eventDao();
eventDao.getEvent().observe(this, event -> {
myTextView.setText(event.get(0));
});
这适用于非常小的东西。但想象我的数据库有一百万个项目。然后当我做这个电话时,会有延迟检索数据。第一次调用它时,用户可以看到存在延迟。怎么避免这个?所以要清楚,有些时候我不想要实时数据,我只需要更新一次视图。我需要知道怎么做?即使它没有使用liveData。
答案 0 :(得分:9)
如果您想同步进行查询而不接收数据集上的更新通知,请不要在LiveData对象中包装返回值。查看Google的示例代码。
看看loadProductSync()here
答案 1 :(得分:6)
有一种方法可以关闭异步并允许同步访问。
在构建数据库时,您可以使用:allowMainThreadQueries()
并且在内存中使用:Room.inMemoryDatabaseBuilder()
虽然不推荐。所以最后我可以使用内存数据库和主线程访问,如果我想要超快速访问。我想这取决于我的数据有多大,在这种情况下非常小。
但是如果你确实想要使用回调....使用rxJava这里是我想要存储在数据库中的国家列表:
public Observable<CountryModel> queryCountryInfoFor(final String isoCode) {
return Observable.fromCallable(new Callable<CountryModel>() {
@Override
public CountryModel call() throws Exception {
return db.countriesDao().getCountry(isoCode);
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}
然后,您可以轻松地将订阅者添加到此函数以使用Rxjava获取回调。
答案 2 :(得分:0)
Bohsen 建议使用实时数据同步查询。但是在某些特殊情况下,我们希望基于逻辑进行一些异步操作。 在下面的示例案例中,我需要获取一些父注释的子注释。它已经在数据库中可用,但是需要在recyclerview适配器中根据其parent_id进行获取。为此,我使用了AsyncTask的return概念来获取结果。 (返回科特林)
存储库类
fun getChildDiscussions(parentId: Int): List<DiscussionEntity>? {
return GetChildDiscussionAsyncTask(discussionDao).execute(parentId).get()
}
private class GetChildDiscussionAsyncTask constructor(private val discussionDao: DiscussionDao?): AsyncTask<Int, Void, List<DiscussionEntity>?>() {
override fun doInBackground(vararg params: Int?): List<DiscussionEntity>? {
return discussionDao?.getChildDiscussionList(params[0]!!)
}
}
道课
@Query("SELECT * FROM discussion_table WHERE parent_id = :parentId")
fun getChildDiscussionList(parentId: Int): List<DiscussionEntity>?