-1

我已经使用 RxJava 以及 Retrofit 和 Mosby/Conductor 创建了一个应用程序。现在我有这个关于视图处理及其相关内容的问题。

考虑以下代码。

public class IndexPresenter extends MvpBasePresenter<IIndexView> {
    @Inject
    VideoService videoService;

    private CompositeDisposable compositeDisposable = new CompositeDisposable();

    private String lastVideoId;

    public IndexPresenter(Context context) {
        // Dagger Inject
    }

    @Override
    public void detachView(boolean retainInstance) {
        compositeDisposable.clear();
        super.detachView(retainInstance);
    }

    public void getTimeline() {
        Disposable disposable = videoService
                .getTimeline(null)
                .delay(5, TimeUnit.SECONDS)
                .compose(Util.schedulers())
                .doOnSubscribe(__ -> getView().startLoading())
                .doFinally(() -> getView().stopLoading())
                .doOnError(throwable -> Timber.d(throwable, "failed getting timeline data"))
                .subscribe(timelineResponse -> {
                    getView().onIndexDataLoaded(timelineResponse.getMeta().getArtists(), timelineResponse.getVideos());
                    int size = timelineResponse.getVideos().size();
                    lastVideoId = timelineResponse.getVideos().get(size - 1).getId();
                }, throwable -> getView().onIndexDataFailed());
        compositeDisposable.add(disposable);
    }

    public void loadMore() {
        if (lastVideoId != null && lastVideoId.equals("-1")) {
            return;
        }
        Disposable disposable = videoService
                .getTimeline(lastVideoId)
                .compose(Util.schedulers())
                .doOnSubscribe(__ -> getView().startLoading())
                .doFinally(() -> getView().stopLoading())
                .doOnError(throwable -> Timber.d(throwable, "failed loading more items"))
                .subscribe(timelineResponse -> {
                    getView().onNextPageLoaded(timelineResponse.getVideos());
                    int size = timelineResponse.getVideos().size();
                    if (size == 0) {
                        lastVideoId = "-1";
                    } else {
                        lastVideoId = timelineResponse.getVideos().get(size - 1).getId();
                    }
                }, throwable -> getView().onIndexDataFailed());
        compositeDisposable.add(disposable);
    }
}

我想知道的是,我每次访问时是否仍然需要执行无效检查getView()?在拆卸之前处理掉所有一次性用品不就可以解决这个问题吗?

4

1 回答 1

3

如果detachView()您像以前一样取消订阅/处置一次性用品

如果RxJava 订阅回调onNext()在 android 主线程上运行(我假设Util.schedulers()设置.observeOn(AndroidSchedulers.mainThread())

那么(只有那时)

保证您永远不会遇到getView()退货的情况null

因为: detachView()被 Mosby 在 android 的主线程上调用。如果onNext回调也运行在 android 的主线程上,那么显然两者都运行在同一个线程上,它们永远不能同时运行,而是一个接一个地运行。因此,执行顺序是:

  1. onNext() 回调 --> 视图仍然是附加的,所以view != null
  2. detachView() --> 取消订阅,因此onNext()永远不会再次调用,并且您永远不会在以下场景中运行view == null

或者

  1. detachView() --> 取消订阅,因此onNext()不再调用
  2. 永远不会发生,因为订阅已被处理,所以永远不要在以下场景中运行view == null

Util.schedulers()在您的具体情况下:我猜您在 android 的主线程(getView() == null

于 2017-03-14T10:50:09.400 回答