Java 在异步写入后不久添加RealmChangeListener时不会执行
长话短说:我不知道为什么我的RealmChangeListener在某些情况下不能按预期触发,我正在寻求有关RealmChangeListener为什么不能工作的建议 更新:我已验证RealmResults保持有效=true;加载=错误。 如果我在添加更改侦听器后执行RealmResults.load,它将在日志中输出一个模糊的抛出异常7,并在我单步遍历领域源时输出一个BadVersionException。我认为这个异常是有意义的,异步写入更新了领域,因此查询似乎不再工作。但是,在MainActivity中写入的executeTransactionAsync以及异步查询都是从主线程启动的 - 我有一个main活动,在该活动中,按下按钮后将执行异步写入 我有另一个按钮,打开显示数据的第二个活动 第二个活动使用一个ViewPager,每个选项卡都有一个片段。每个选项卡都有不同的查询 现在发生的事情如下:我打开第二个活动,它实例化了四个片段,而不是将它们附加到活动 然后,活动执行查询,将每个RealmResults传递给片段,在片段中安装RealmChangeListener以在加载数据后显示数据。当片段未附加到活动时,RealmChangeListener是否会不工作 无论如何,这是片段中的方法,它接收findAllAsyncSorted创建的RealmResults,并且应该更新适配器上的数据:Java 在异步写入后不久添加RealmChangeListener时不会执行,java,android,realm,realm-java,Java,Android,Realm,Realm Java,长话短说:我不知道为什么我的RealmChangeListener在某些情况下不能按预期触发,我正在寻求有关RealmChangeListener为什么不能工作的建议 更新:我已验证RealmResults保持有效=true;加载=错误。 如果我在添加更改侦听器后执行RealmResults.load,它将在日志中输出一个模糊的抛出异常7,并在我单步遍历领域源时输出一个BadVersionException。我认为这个异常是有意义的,异步写入更新了领域,因此查询似乎不再工作。但是,在MainAc
public void updateData(OrderedRealmCollection<Bean> realmCollection) {
Timber.v("Delegated data to fragment of adapter %s.", adapter);
this.data = (RealmResults<Bean>) realmCollection;
if (data.isLoaded()) {
Timber.d("Data is already loaded on adapter %s.", adapter);
adapter.updateDataManual(data);
}
if (!data.isValid()) {
Timber.e("Data is not valid.");
}
listener = new RealmChangeListener<RealmResults<Bean>>() {
@Override public void onChange(RealmResults<Bean> newResults) {
Timber.v("Change listener for manual data triggered: %d results in fragment for category %s and adapter %s.",
newResults.size(), category.toString(), adapter);
adapter.updateDataManual(newResults);
}
@Override protected void finalize() throws Throwable {
Timber.d("Finalizing change listener for adapter %s.", adapter);
super.finalize();
}
};
data.addChangeListener(listener);
MyTimer.setRepeatingCallback(() -> {
Timber.v("RealmResults in adapter %s are %s and %s, and the ChangeListener is %s.",
adapter,
data.isValid() ? "valid" : "invalid",
data.isLoaded() ? "loaded" : "not loaded",
listener);
return true;
}, 5000);
}
如您所见,我努力确保查询是有效的,并且在添加更改侦听器之前不会加载查询,并且RealmResults和RealmChangeListener都不会被垃圾收集
尽管如此,在四个RealmChangeListener中,只有两个或更少的有时是零触发
请注意,仅当在MainActivity上启动异步写入后不久打开第二个activity时,才会发生这种情况。如果我等2秒钟,一切都正常。我确实验证了RealmChangeListener没有被垃圾收集,因为finalize是在退出应用程序后调用的。我不知道什么会阻止听众工作。我有什么特别需要注意的吗 您需要有一个对RealmResults的强字段引用,以防止它得到GC'd
如果RealmResults获得GC'd,则Realm无法再自动更新它。当方法完成时,您的数据对象超出范围,因此很可能是GC'd。您需要将其保存在类变量中。@ChristianMelchior我也是这么想的,但他有这个。data=RealmResults realmCollection;这意味着结果应该已经保存为一个字段变量-但是如果他交换掉它,那么yes@ChristianMelchior实际上,我将其存储在一个字段中,该字段只能从POST方法访问。现在我正在尝试编写一个测试类,希望我能重现那里的问题。@EpicPandaForce在添加更改侦听器后直接调用RealmResults上的load时,我将问题缩小为BadVersionException。异常的描述非常有意义,即在异步写入完成后,对于领域的最新状态,查询不可用。也许这与使用单独的领域实例有关。这在领域Java 3.0.0中已被修复。事实上,我将其存储在一个只能通过POST方法访问的字段中。现在我正在尝试编写一个测试类,希望我可以重现那里的问题。另外,如果关闭结果集所属的领域实例,那么将不再调用属于该领域实例的结果的RealmChangeListeners,因为结果集已失效。嗯,我知道你们很难在看不到我的代码的情况下进行远程调试。现在,我添加了一个计时器,它每五秒钟打印一次以下内容:Timber.vRealmResults在适配器%s中是%s,ChangeListener是%s。。适配器,data.isValid?有效:无效,侦听器;RealmResults有效,侦听器未被垃圾收集。我将看看是否可以在仪器化测试中重现它,遗憾的是,第一次尝试并没有重现问题。