【问题标题】:Why is onNext not getting called when using toList?为什么在使用 toList 时没有调用 onNext?
【发布时间】:2016-10-04 00:37:53
【问题描述】:

在使用 RxJava toList 运算符时,我遇到了 onNext 没有被调用的问题。在调用toList 之前,一切都按我的预期工作。我读过的东西hereherehere 似乎表明onCompleted 没有被调用的问题,但我还是 RxJava 的新手,所以我不确定我需要在哪里调用它为了让它工作。

最令人困惑的是,我试图从 Google's Android Architecture 遵循的架构似乎并没有调用 onCompleted,而且它工作得很好。

Subscription subscription = mDataSource
        // Get Observable<List<Location>> from SQLBrite database
        .getLocations()
        // Convert to Location object
        .flatMap(new Func1<List<Location>, Observable<Location>>() {
            @Override
            public Observable<Location> call(List<Location> locations) {
                return Observable.from(locations);
            }
        })
        // Filter here
        .filter(new Func1<Location, Boolean>() {
            @Override
            public Boolean call(Location location) {
                return mPreferences.getUsesCustomLocations() || location.getId().length() <= 2;
            }
        })
        // Convert Location object to String
        .map(new Func1<Location, String>() {
            @Override
            public String call(Location location) {
                return location.getTitle();
            }
        })
        // Convert to Observable<List<String>, however using toList()
        // causes onNext() to never get called
        .toList()
        .subscribeOn(mSchedulerProvider.computation())
        .observeOn(mSchedulerProvider.ui())
        .subscribe(new Observer<List<String>>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
                e.printStackTrace();
            }

            @Override
            public void onNext(List<String> locations) {
                processLocations(locations);
            }
        });
    mSubscriptions.add(subscription);

【问题讨论】:

    标签: android rx-java rx-android sqlbrite


    【解决方案1】:

    在调用toList() 之后,你只会得到一个onNext(),这就是源observable 调用onComplete() 的时候。

    您所看到的行为的原因是 SQLBrite,它会在每次更改数据时向您发送数据。 这意味着它是一个无休止的流,因此它最终永远不会调用 onComplete()。

    【讨论】:

    • 感谢您将问题连接到 SQLBrite。我链接的 Google 存储库也使用 SQLBrite,并且能够调用 toList,所以我觉得应该有一些解决方法。
    • @apicellaj 它不直接使用 SQLBrite。 github.com/googlesamples/android-architecture/blob/… 在这里他们尝试检索远程值和缓存值并在第一个值处截断 (.first()) 所以在示例中 getTasks() 只返回一个列表。
    • 在我的Observable&lt;List&lt;Location&gt;&gt; 数据库查询中调用(.first()) 解决了这个问题!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多