RxJava Observable从不执行onCompleted

时间:2017-05-09 15:40:23

标签: android realm rx-java observable realm-mobile-platform

我使用RxJavaRealm来查询移动数据库。我需要通知我的视图在查询完成时更新列表但似乎flatMapdoOnNext工作,但它永远不会继续完成。我需要一个触发器才能知道它结束了。

Realm.getDefaultInstance().asObservable().flatMap((realm) ->
        realm.where(FileDoc.class).isNull("parent").isNotNull("updatedDate").findAllSortedAsync("name").asObservable()
                .flatMap((files) -> {
                    documents.get("root").clear();
                    documents.get("root").addAll(realm.copyFromRealm(files));
                    return realm.where(Folder.class).isNull("parent").findAllSortedAsync("name").asObservable().doOnCompleted(() -> {
                        Log.e(TAG, "Barr!");
                    });
                })
                .doOnNext((folders) -> {
                    documents.get("root").addAll(realm.copyFromRealm(folders));
                })).doOnCompleted(() -> Log.e(TAG, "Fooo!"))
        .doOnError(error -> handleErrorEvent(error))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(AndroidSchedulers.from(backgroundLooper))
        .subscribe();

此处Barr!Fooo!从未打印过......任何人都有线索?

已更新

Realm.getDefaultInstance().asObservable().first().flatMap((realm) ->
                realm.where(IncidentTemplate.class).equalTo("deleted", false).findAllAsync().asObservable()
                        .filter(results -> results.isLoaded())
                        .first()
                        .doOnNext((files) -> {
                            if (!incidents.containsKey("INCIDENT")) {
                                incidents.put("INCIDENT", new ArrayList<>());
                            }

                            incidents.get("INCIDENT").clear();
                            incidents.get("INCIDENT").addAll(realm.copyFromRealm(files));

                        })
                        .doOnTerminate(() -> {
                            Log.e(TAG, "Closing realm");
                            realm.close();
                        }))
                .doOnCompleted(() -> {
                    emitStoreChange(new CobaltStore.CobaltStoreChangeEvent());
                    Log.e(TAG, "EMIT INCIDENT");
                })
                .doOnError(error -> handleErrorEvent(error))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(AndroidSchedulers.from(backgroundLooper))
                .subscribe();

1 个答案:

答案 0 :(得分:1)

1。)Realm.getDefaultInstance().asObservable()

您获得了一个永远无法关闭的本地Realm实例,因此您正在泄漏内存。

2。)这不是asObservable()设计工作的方式。

OnClickListener完成并发出终端事件是否有意义?

例如,您单击按钮一次,然后可观察的&#34;完成&#34;并且永远不会再发出任何事件,即使用户之后点击了按钮?

当然不是,因此你不应该期望它来自Realm的RealmChangeListener;这是绑定到Realm或RealmResults的内容,这样您就可以收听将来对Realm或其特定表所做的任何写入。

解决方案可能只是使用

之类的东西
Observable.fromCallable(() => {
    try(Realm realm = Realm.getDefaultInstance()) {
        RealmResults<FileDoc> docs = realm.where(FileDoc.class)
             .isNull("parent")
             .isNotNull("updatedDate")
             .findAllSorted("name");
        documents.get("root").clear(); // <-- shouldn't you modify a new copy and return this?
        List<FileDoc> unmanagedDocs = realm.copyFromRealm(files);
        documents.get("root").addAll(unmanagedDocs);
        return unmanagedDocs;
    }
}

或者正如您所指出的,.filter((data) -> data.isLoaded()).first()也有效,尽管我没有想到这一点。