Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在异步写入后不久添加RealmChangeListener时不会执行_Java_Android_Realm_Realm Java - Fatal编程技术网

Java 在异步写入后不久添加RealmChangeListener时不会执行

Java 在异步写入后不久添加RealmChangeListener时不会执行,java,android,realm,realm-java,Java,Android,Realm,Realm Java,长话短说:我不知道为什么我的RealmChangeListener在某些情况下不能按预期触发,我正在寻求有关RealmChangeListener为什么不能工作的建议 更新:我已验证RealmResults保持有效=true;加载=错误。 如果我在添加更改侦听器后执行RealmResults.load,它将在日志中输出一个模糊的抛出异常7,并在我单步遍历领域源时输出一个BadVersionException。我认为这个异常是有意义的,异步写入更新了领域,因此查询似乎不再工作。但是,在MainAc

长话短说:我不知道为什么我的RealmChangeListener在某些情况下不能按预期触发,我正在寻求有关RealmChangeListener为什么不能工作的建议

更新:我已验证RealmResults保持有效=true;加载=错误。 如果我在添加更改侦听器后执行RealmResults.load,它将在日志中输出一个模糊的抛出异常7,并在我单步遍历领域源时输出一个BadVersionException。我认为这个异常是有意义的,异步写入更新了领域,因此查询似乎不再工作。但是,在MainActivity中写入的executeTransactionAsync以及异步查询都是从主线程启动的

-

我有一个main活动,在该活动中,按下按钮后将执行异步写入

我有另一个按钮,打开显示数据的第二个活动

第二个活动使用一个ViewPager,每个选项卡都有一个片段。每个选项卡都有不同的查询

现在发生的事情如下:我打开第二个活动,它实例化了四个片段,而不是将它们附加到活动

然后,活动执行查询,将每个RealmResults传递给片段,在片段中安装RealmChangeListener以在加载数据后显示数据。当片段未附加到活动时,RealmChangeListener是否会不工作

无论如何,这是片段中的方法,它接收findAllAsyncSorted创建的RealmResults,并且应该更新适配器上的数据:

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有效,侦听器未被垃圾收集。我将看看是否可以在仪器化测试中重现它,遗憾的是,第一次尝试并没有重现问题。