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

                    前段时间使用了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中有一种方式能够很简单的解除这种引用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小阳世界2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值