我有以下情况:我需要从数据库获取数据。当我尝试进入 UI 线程时(这是我的做法):
List<Movie> movies = new ArrayList<>();
for (MovieEntity movie:movieDao.getFavorites()){
movies.add(getMovie(movie));
}
mView.onMoviesLoaded(movies);
一切正常
但是当我在 rx 中执行此操作时:
mCompositeDisposable.add(movieDao.getFavorites()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe(disposable -> mView.showLoadingIndicator(true))
.doOnError(throwable -> {
mView.showLoadingIndicator(false);
mView.showEmptyState(true);
})
.doOnTerminate(() -> mView.showLoadingIndicator(false))
.doOnComplete(()->mView.showLoadingIndicator(false))
.flatMapIterable(listObservable -> listObservable)
.map(this::getMovie)
.toList()
.subscribe(list -> {
if (list.isEmpty()) {
mView.showEmptyState(true);
} else {
mView.onMoviesLoaded(list);
}
})
);
我一直有加载指示器。我无法理解为什么会发生这种情况,因为我为所有情况(错误和成功情况)添加了 showLoadingIndicator(false)
。那么,为什么它没有移走并且没有显示数据?
最佳答案
movieDao.getFavorites()
是无限的流。使用.toList()
在无限流上没有意义,因为 .toList()
在源流完成之前不会发出。
有两个选项:
- 让你的资源有限
制造movieDao.getFavorites()
返回 Single<List<MovieEntity>>
而不是Observable<List<MovieEntity>>
或者简单地说.take(1)
在来源之后。
mCompositeDisposable.add(movieDao.getFavorites()
.take(1) // This will terminate the stream after it emits first item.
.subscribeOn(Schedulers.io())
...
- 或者,不要使用
.toList()
.
保持无限流并继续监听数据库更改。
mCompositeDisposable.add(movieDao.getFavorites()
.map(movieEntities -> movieEntities.stream().map(this::getMovie).collect(Collectors.toList()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(list -> {
if (list.isEmpty()) {
mView.showEmptyState(true);
} else {
mView.onMoviesLoaded(list);
}
})
);
关于java - 不调用方法 doOnComplete、doOnTerminate 或 doOnError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56569359/