mvp 内存泄露处理方案

阅读本文大概需要5分钟

由于Presenter经常性地需要执行一些耗时的操作,例如,我们经常使用的网络请求数据。当 Presenter 持有了 Activity 的强引用,如果在请求结束之前,Activity 被销毁了,那么由于网络请求还没有返回,导致 Presenter 一直持有 Activity 对象的引用,使得该对象无法被系统回收,此时就发生了内存泄露。

解决方案:通过弱引用和 Activity / Fragment 的生命周期来解决这个问题。

/**
* Presenter抽象类。
*/
public abstract class BasePresenter<T> {
protected Reference<T> mViewRef;
public void attachView(T view){
mViewRef = new WeakReference<T>(view); //建立连接
}
protected T getview(){
return mViewRef.get();
}
public boolean isViewAttach(){
return mViewRef != null && mViewRef.get() != null;
}
public void detachView(){
if(mViewRef != null){
mViewRef.clean();
mViewRef = null;
}
}
}

BasePresenter 有 4 个方法,分别与 View 建立关联、解除关联、判断是否与 View 建立了关联、获取 View。View类型通过 BasePresenter 的泛型传递进来,Presenter 对这个 View 持有弱引用,通常这种情况下这个 View 类型应该是实现了某个特定的接口的 Activity 或者 Fragment 等类型。

/**
* MVPBaseActivity 基类。
*/
public abstract class MVPBaseActivity<V , T extends BasePresenter<V>> extends Activity{
protected T mPresenter;
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mPresenter = createPresenter(); //创建 Presenter
mPresenter.attachView((V)this);
}
protected void onDestory(){
super.onDestory();
mPresenter.detachView(); //销毁
}
private abstract T createPresenter(); // 由子类实现具体的 Presenter
}

MVPBaseActivity 含有两个泛型参数。第一个是 View 接口的类型,第二个是 Presenter 的具体类型。通过泛型参数,使得一些通用的逻辑可以被抽象到 MVPBaseActivity 当中。例如,在 MVPBaseActivity 的 onCreate 函数中,会通过 createPresenter() 创建一个具体的 Presenter,这个 Presenter 的类型就是 BasePresenter 类型。构建 Presneter 之后调用 attachView() 与 Activity 建立关联。而在 onDestory() 中解除了对 Activity 的引用。

public class MyActivity extends MVPBaseActivity<ViewInterface,MyPresenter>
implement ViewInterface{
protected void onCreate(Bunlde saveInstanceState){
spuer.onCraete(saveInstanceState);
initView();
mPresenter.getMessage();
}
//代码省略
}

此时,Presenter 的创建以及与 View 建立关联等操作都被封装到了 MVPBaseActivity 中,消除了子类重复代码的同时又避免了 Activity 的内存泄露问题。

本文选取自《Android源码设计模式解析与实战》中的MVP章节内容

RiderWu wechat
欢迎您扫一扫上面的微信公众号,目前试运营当中。