Android -room持久库 - DAO调用是异步的,因此如何获得回调?

j2e*_*nue 17 android android-room

从我所读的内容Room不允许您在主线程上发出数据库查询(因为可能导致主线程的延迟)). 所以想象一下,我正在尝试更新UI主线程上的textview哪些数据如何才能收到回调.让我举个例子.想象一下,我想将我的业务模型数据存储到一个名为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);

}
Run Code Online (Sandbox Code Playgroud)

现在在一些活动中,我有一个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 ?*/
Run Code Online (Sandbox Code Playgroud)

因为提取是从主线程发生的,我不认为我可以这样称呼并期望平滑更新.什么是最好的方法?

更多信息:我想使用会议室数据库作为检索模型信息的机制,而不是将其静态保存在内存中.因此,通过休息服务下载后,我可以通过数据库在本地使用该模型.

更新:所以既然我正在返回一个liveata,那么我可以这样做:

eventDao = eventDatabase.eventDao();
eventDao.getEvent().observe(this, event -> {
     myTextView.setText(event.get(0));
});
Run Code Online (Sandbox Code Playgroud)

这适用于非常小的东西.但想象我的数据库有一百万个项目.然后当我做这个电话时,会有延迟检索数据.第一次调用它时,用户可以看到存在延迟.怎么避免这个?所以要清楚,有些时候我不想要实时数据,我只需要更新一次视图.我需要知道怎么做?即使它没有使用liveData.

Boh*_*sen 12

如果要同步执行查询而不接收数据集上的更新通知,则不要将返回值包装在LiveData对象中.查看Google的示例代码.

这里看一下loadProductSync()


j2e*_*nue 7

有一种方法可以关闭异步并允许同步访问.

构建数据库时,您可以使用: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());
Run Code Online (Sandbox Code Playgroud)

}

然后,您可以轻松地将订阅者添加到此函数以使用Rxjava获取回调.