领域计数不正确/不一致主线程

问题描述:

我看到一个非常奇怪的问题,从主线程上运行的查询中获取计数。我有一个使用适用于Realm的RecyclerView适配器的用户界面,它的工作原理很简单。领域计数不正确/不一致主线程

我有一个方法可以计算查询前的记录数,因此它可以设置一个起点,出于某种原因,它将返回前一个计数在最后一个事务之前。这里是一个略微缩短的版本与日志的输出:

D/SearchController: Query Count (Main Thread): 50 
D/SearchController: Query Count (Rx Thread): 50 
D/SearchController: Query Count (Main Thread): 100 
D/SearchController: Query Count (Rx Thread): 50 

public Single<Update> searchWithCriteriaForMore(SearchCriteria searchCriteria) { 
     Realm realmI = Realm.getDefaultInstance(); 
     Timber.d("Query Count (Main Thread): %d", realmI.where(Ad.class).equalTo("searchId", searchCriteria.id()).count()); 
     realmI.close(); 
     return Single.defer(() -> { 
      Realm realm = Realm.getDefaultInstance(); 
      Timber.d("Query Count (Rx Thread): %d", realm.where(Ad.class).equalTo("searchId", searchCriteria.id()).count()); 
      realm.close(); 
// Stuff to add records on Rx Thread 
     }); 
    } 

调用看起来是这样的:

SearchController.instance().searchWithCriteriaForMore(searchCriteria) 
    .subscribeOn(Schedulers.io()) 
    .observeOn(AndroidSchedulers.mainThread()) 
    .subscribe(new SingleSubscriber<SearchController.Update>() { 
     ... 
    } 

思考的人?我一直在试图将这个问题讨论几个星期,认为这是我正在做的事情,但是如果我在主线程中进行计数并将其传入,它就可以正常工作。

我正在运行RxJava 1.2.7,RxAndroid 1.2.1和Realm 3.3.1。

+0

感谢您的想法,我使用minSdk 16,所以不能使用资源的想法,但我确实把计数放在一个事务中,现在它正在得到正确的计数。这不应该是必要的,但猜猜这就是生活。 – Kenny

+0

Nah,实际上你可以在Realm.getDefaultInstance()之后用'realm.refresh()'替换它,如果你使用的是Realm 3.2+ – EpicPandaForce

感觉你在RxThread之前没有关闭过的Realm实例。由于RxThread没有活套,领域实例不能自动更新。所以它在创建时被锁定在版本中。

领域内部使用ref计数器,getDefaultInstance()只会返回您之前在RxThread上打开的同一个实例。

解决方案: 1.找出在RxThread上检索哪个Realm实例并正确关闭它。所以下一次getDefaultInstance()会以最新的版本数据返回一个新的Realm实例。 2.如果要在RxThread上创建Realm实例,可以拨打realm.refresh()手动将其移动到最新的数据版本。