# main(1)
java.lang.NullPointerException
Attempt to invoke virtual method 'boolean com.example.view.SuperSwipeRefreshLayout.post(java.lang.Runnable)' on a null object reference
这个崩溃是怎么发生的呢?原因很简单,工作线程执行网络请求,如果这个请求执行的时间过久(由于网络延迟等原因),Activity或者Fragment已经不存在了(被销毁了),而线程并不知道这件事,这时候请求数据结果回来以后,将数据通过Handler抛给了主线程,在异步回调里一般都会执行数据的更新或者进度条的更新等操作,但页面已经不存在了,所以就GG了。。。
以下摘自MVP开发模式中Presenter中的需要注意的内容
这里没有在构造函数中出入View,而是抽出两个attachView和destroyView,同步在Activity或者Fragment中的onCreate和onDestroy中进行View的绑定。同时抽出一个isViewAttached进行View的判空,这是为了防止Activity或者Fragment被意外退出,Presenter的异步网络请求返回,这时候就会有空指针异常。
public abstract class BasePresenter<V extends Contract.View> implements Contract.Presenter {
protected V view;
public BasePresenter() {
}
public void attachView(V view){
this.view = view;
}
public void destroyView(){
this.view = null;
}
protected boolean isViewAttached(){
return this.view != null;
}
}
目前的解决方案
有人会问,框架设计者怎么会没有考虑到这个问题?实际上他们确实考虑了这个问题。目前来说有两种解决方案:
在Activity结束时取消请求
- 在异步回调的时候,通过Activity.isFinishing()方法判断Activity是否已经被销毁
- 通过RxLifecycle解决RxJava中对于生命周期事件的监听
- 这两种方案本质是一样的,就是判断Activity是否被销毁,如果销毁,则要么取消回调,要么不执行回调。