Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 通过Mosby使用RxJava2避免NPE_Android_Nullpointerexception_Rx Java2_Mosby - Fatal编程技术网

Android 通过Mosby使用RxJava2避免NPE

Android 通过Mosby使用RxJava2避免NPE,android,nullpointerexception,rx-java2,mosby,Android,Nullpointerexception,Rx Java2,Mosby,我已经使用RxJava以及改装和Mosby/Conductor创建了一个应用程序。现在我有一个关于视图处理的问题,以及与之相关的内容 考虑以下代码 public class IndexPresenter extends MvpBasePresenter<IIndexView> { @Inject VideoService videoService; private CompositeDisposable compositeDisposable = new C

我已经使用RxJava以及改装和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);
    }
}
公共类IndexPresenter扩展了MvpBasePresenter{
@注入
视频服务;
私有CompositeDisposable CompositeDisposable=新CompositeDisposable();
私有字符串lastVideoId;
公共IndexPresenter(上下文){
//匕首注射
}
@凌驾
公共视图(布尔保留实例){
compositeDisposable.clear();
super.detactinView(保持状态);
}
public void getTimeline(){
一次性视频服务
.getTimeline(空)
.延迟(5,时间单位。秒)
.compose(Util.schedulers())
.doOnSubscribe(\uu->getView().starting())
.doFinally(()->getView().stopLoading())
.doon错误(throwable->Timber.d(throwable,“获取时间线数据失败”))
.订阅(timelineResponse->{
getView().onIndexDataLoaded(timelineResponse.getMeta().getArtists(),timelineResponse.getVideos());
int size=timelineResponse.getVideos().size();
lastVideoId=timelineResponse.getVideos().get(大小-1.getId();
},throwable->getView().onIndexDataFailed());
可合成。添加(一次性);
}
public void loadMore(){
如果(lastVideoId!=null&&lastVideoId.equals(“-1”)){
返回;
}
一次性视频服务
.getTimeline(lastVideoId)
.compose(Util.schedulers())
.doOnSubscribe(\uu->getView().starting())
.doFinally(()->getView().stopLoading())
.doon错误(throwable->Timber.d(throwable,“加载更多项目失败”))
.订阅(timelineResponse->{
getView().onNextPageLoaded(timelineResponse.getVideos());
int size=timelineResponse.getVideos().size();
如果(大小==0){
lastVideoId=“-1”;
}否则{
lastVideoId=timelineResponse.getVideos().get(大小-1.getId();
}
},throwable->getView().onIndexDataFailed());
可合成。添加(一次性);
}
}

我想知道的是,每次访问
getView()
时是否仍必须执行空性检查?拆下之前处理掉所有的一次性用品不就要注意这一点吗?

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

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

然后(只有那时)

可以保证您永远不会遇到
getView()
返回
null
的情况

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

  • onNext()回调-->视图仍处于连接状态,因此
    view!=空
  • detachView()-->取消订阅,因此不再调用
    onNext()
    ,也不再在
    view==null
  • detachView()-->取消订阅,因此不再调用
    onNext()
  • 决不会发生,因为已释放订阅,所以决不会在
    view==null

  • 在您的特定情况下:我猜您在android的主线程(
    Util.schedulers()
    )上观察到了,并且您也正确地处理了可观察的对象,因此您永远不会在
    getView()中运行==null

    您可以在构造函数上发送
    视图本身,并使用@NonNull@hrskrsMosby将
    视图
    自动传输到
    onAttach
    中的演示者。对不起,我没有注意到。有关
    Null
    ibility检查,请参阅非常感谢Hannes。你猜对了
    Util.schedulers()
    sets.observeOn(AndroidSchedulers.mainThread())。