簡體   English   中英

多次訂閱RxJava observable

[英]Subscribe on RxJava observable multiple times

我有一個關於RxJava Observable的問題。 例如,我有一個Retrofit接口,它返回Observable。 我需要對這個視頻流做一些事情。 以下是下載視頻並將其保存到列表中的代碼:

API.getVideoListObservable()
                .doOnError(t -> t.printStackTrace())
                .map(r -> r.getObjects())
                .doOnNext(l -> VideoActivity.this.runOnUiThread(() -> fragment.updateVideoList(l)))
                .doOnNext(l -> kalturaVideoList.addAll(l))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();

API - 改造休息適配器

如果想更新視頻列表, 我應該做同樣的操作嗎? 或者我應該訂閱,取消訂閱並再次訂閱如下:

Subscription s = API.getVideoListObservable()
                .doOnError(t -> t.printStackTrace())
                .map(r -> r.getObjects())
                .doOnNext(l -> VideoActivity.this.runOnUiThread(() -> fragment.updateVideoList(l)))
                .doOnNext(l -> kalturaVideoList.addAll(l))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();

//some code
...

s.unsubscribe();
s = null;
s = API.getVideoListObservable()
                .doOnError(t -> t.printStackTrace())
                .map(r -> r.getObjects())
                .doOnNext(l -> VideoActivity.this.runOnUiThread(() -> fragment.updateVideoList(l)))
                .doOnNext(l -> kalturaVideoList.addAll(l))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe();

您的整個事件流是錯誤的,您應該更新訂閱者的UI,而不是doOnNext。

API.getVideoListObservable()
    .map(r -> r.getObjects())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(videos -> {
        // do stuff with videos
        fragment.updateVideoList(videos);
        kalturaVideoList.addAll(videos);
    }, throwable -> {
        // handle errors
        throwable.printStackTrace();
    });

Retrofit為您設置subscribeOn(Schedulers.io())

將所有內容移動到一個函數中,並在需要更新列表時調用它。 無需手動取消訂閱,因為訂閱者在收到onCompleted或onError時會自動取消訂閱。

請注意,在Android上使用RxJava時,您必須處理Activity / Fragment生命周期和配置更改。 您必須跟蹤待處理的網絡呼叫,並在用戶導航到另一個活動/片段時手動取消訂閱。

解決我到目前為止遇到的所有RxJava + Android問題的首選方法是使用https://github.com/evant/rxloader庫。 使用RxLoader的代碼如下所示:

private Observable<List<Video>> getVideos() {
    return API.getVideoListObservable()
        .map(r -> r.getObjects());
}

// in onCreate()
RxLoaderManager loaderManager = RxLoaderManager.get(this);
RxLoader<List<Video>> videoLoader = loaderManager.create(
    getVideos().observeOn(AndroidSchedulers.mainThread()),
    new RxLoaderObserver<List<Video>>() {
        @Override
        public void onNext(List<Video> videos) {
            // do stuff with videos
            fragment.updateVideoList(videos);
            kalturaVideoList.addAll(videos);
        }

        @Override
        public void onError(Throwable throwable) {
            // handle errors
            throwable.printStackTrace();
        }
    });

// whenever you need to update videos
videoLoader.restart();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM