Android 开发使用MVP产生的内存泄露问题

来源:互联网 发布:淘宝以前的聊天记录 编辑:程序博客网 时间:2024/06/18 12:28

                    前段时间使用了mvp写了一个项目,发现这个模式很好用,然后用androidstudio自带的内存检查工具检查,发现好几处内存泄露,其实原因很简单,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;    }

内存泄露就基本解决。

但是我记得Rxjava中有一种方式能够很简单的解除这种引用。

0 0
原创粉丝点击