在上一篇我们说道,MVP中由于P对V(Activity)的引用可能导致内存泄漏。
我们都知道,当我们使用非静态内部类,或者匿名内部类的时候,由于内部类会默认持有外部类的引用,当我们在内部类中进行耗时操作时,就会长时间保持对外部类的引用导致资源无法释放产生泄漏的可能。
下面Presenter的基类,我们将P对V的引用改成了弱引用的方式,同时结合Acitivty的生命周期去进行attachView和dettach,解除P、V的绑定。
public class BasePresenter<T> {
public Reference<T> mViewRef;
protected CompositeSubscription mCompositeSubscription;
public void attachView(T mView){
mCompositeSubscription = new CompositeSubscription();
mViewRef = new WeakReference<>(mView);
}
public T getView(){
if (mViewRef!=null) {
return mViewRef.get();
}
return null;
}
public void dettach(){
if (mCompositeSubscription!=null&&mCompositeSubscription.isUnsubscribed()){
mCompositeSubscription.unsubscribe();
}
if (mViewRef!=null){
mViewRef.clear();
mViewRef=null;
}
}
}
下面Activity的基类,可以看到在基类Acitivity中我们将P根据生命周期进行了绑定和解绑工作
public abstract class BaseMvpActivity<V,T extends BasePresenter<V>> extends SwipeBackActivity {
private T presenter;
@SuppressWarnings(value = {"unchecked"})
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = initPresenter();
presenter.attachView((V)this);
}
protected abstract T initPresenter();
@Override
protected void onDestroy() {
super.onDestroy();
presenter.dettach();
presenter=null;
}
}
这样我们在PresenterImpl和Activiity中,就很明了了
public class TestDetailPresenterImpl extends BasePresenter<TestDetailView>{
private TestDetailModel testDetailModel;
public TestDetailPresenterImpl(){
testDetailModel = new TestDetailModelImpl();
}
public void loadTest(String topicId,String userid) {
Subscription testSubscription = testDetailModel.loadTest(topicId, userid)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<SubjectBean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if (e != null&&getView()!=null) {
getView().showLoadResult(e.getMessage());
}
}
@Override
public void onNext(SubjectBean subjectBean) {
SubjectBean.ObjectBean objectBean = subjectBean.getObject();
if (getView()!=null) {
getView().addTestData(objectBean);
}
}
});
mCompositeSubscription.add(testSubscription);
}
public class TestDetailActivity extends BaseMvpActivity<TestDetailView,TestDetailPresenterImpl> implements TestDetailView {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_detail);
}
@Override
protected TestDetailPresenterImpl initPresenter() {
testDetailPresenter = new TestDetailPresenterImpl();
return testDetailPresenter;
}
这样我们就基本解决了MVP导致的内存泄漏问题