Android开发:浅谈MVP模式应用与内存泄漏

最近博主开始在项目中实践MVP模式,却意外发现内存泄漏比较严重,但却很少人谈到这个问题,促使了本文的发布,本文假设读者已了解MVP架构。

本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it

MVP简介

M-Modle,数据,逻辑操作层,数据获取,数据持久化保存。比如网络操作,数据库操作

V-View,界面展示层,Android中的具体体现为Activity,Fragment

P-Presenter,中介者,连接Modle,View层,同时持有modle引用和view接口引用

上图摘自阮一峰大神博客:MVC,MVP 和 MVVM 的图示

注:有别于MVC,Activity,Fragment通常被用作Controller和View使用,加重了它的职责。在MVP中,Activity,Fragment仅用做View层展示

示例代码

本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it

Modle层操作

public class TestModle implements IModle{
    private CallbackListener callback;

    public TestModle(CallbackListener callback) {
        this.callback = callback;
    }
    public interface CallbackListener {
        void onGetData(String data);
    }
    public void getData() {
        new Thread() {
            public void run() {
                callback.onGetData("返回的数据");
            }
        }.start();
    }
}

View层

// 抽象的view层
public interface TestViewInterf extends IView {
    void onGetData(String data);
}

// 具体的View层
public class MainActivity extends Activity implements TestViewInterf{
    private TestPresenter mTestPresenter;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // view层将获取数据的任务委派给中介者presenter,并传入自身实例对象,实现TestViewInterf接口
        mTestPresenter = new TestPresenter(this);
        mTestPresenter.getData();
    }

    @Override
    public void onGetData(String data) {
        // View层只做数据展示
        showToast(data);
    }

    private void showToast(String toast) {
        Toast.makeText(this, toast, Toast.LENGTH_LONG).show();
    }
}

Presenter中介者

public class TestPresenter implements IPresenter{
    IModle modle;
    IView view;
    public TestPresenter(IView view) {
        this.view = view;
    }

    public void getData() {
        // 获取数据的操作实际在Modle层执行
        modle = new TestModle(new CallbackListener() {
            public void onGetData(String data) {
                if (view != null) {
                    view.onGetData(data);
                }
            }
        });
        modle.getData();
    }
}

根据OOP思想,Java应面向接口编程,这样才能给符合OCP原则。上述示例代码省略了更加抽象的接口IModle,IView,IPresenter,并且实际MVP实践中通常会引入泛型使其更具扩展性。

Google已提供了相关示例代码,并在MVP中增加了一个约束者:Contract,它的作用是定义各个模块的MVP接口。

google MVP sample code:https://github.com/googlesamples/android-architecture

内存泄露问题

由上可见,Presenter中持有View接口对象,这个接口对象实际为MainActivity.this,Modle中也同时拥有Presenter对象实例,当MainActivity要销毁时,Presenter中有Modle在获取数据,那么问题来了,这个Activity还能正常销毁吗?

答案是不能!

当Modle在获取数据时,不做处理,它就一直持有Presenter对象,而Presenter对象又持有Activity对象,这条GC链不剪断,Activity就无法被完整回收。

换句话说:Presenter不销毁,Activity就无法正常被回收。

解决MVP的内存泄露

Presenter在Activity的onDestroy方法回调时执行资源释放操作,或者在Presenter引用View对象时使用更加容易回收的软引用,弱应用。

比如示例代码:

Activity

@Override
    public void onDestroy() {
        super.onDestroy();
        mPresenter.destroy();
    }

Presenter

public void destroy() {
    view = null;
    if(modle != null) {
        modle.cancleTasks();
    }
}

Modle

public void cancleTasks() {
    // TODO 终止线程池ThreadPool.shutDown(),AsyncTask.cancle(),或者调用框架的取消任务api
}

本文原创作者:xiong_it,链接:http://blog.csdn.net/xiong_it


个人总结

因为面向MVP接口编程,可适应需求变更,所以MVP适用于比较大的项目;因为其简化了Activity和Fragmnt的职责,可大大减少View层的代码量,比起MVC中Activity,Fragment动不动上千行的代码量,简直优雅!

做完以上操作,由于MVP引起的内存泄露就差不多解决了,祝大家撸码愉快!欢迎留言区交流指正。

时间: 2024-10-14 14:23:37

Android开发:浅谈MVP模式应用与内存泄漏的相关文章

Android开发-浅谈架构(二)

写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应该不是这样,但是我想说的是 自从我想写一些笔记记录知识的时候 为了不误导其他人 我不得不参考github 一些比较知名大牛的代码.在这个过程中 我下载过很多demo.一点一点的啃 汲取精华的部分 当然也充满疑惑.后来觉得标题取得有点大了 我应该取"学习"类的标题才对.但是另一方面我也只能就

浅谈 MVP in Android(转)

我自己写的demo:https://pan.baidu.com/s/1dFImVYD 一.概述 对于MVP(Model View Presenter),大多数人都能说出一二:“MVC的演化版本”,“让Model和View完全解耦”等等.本篇博文仅是为了做下记录,提出一些自己的看法,和帮助大家如何针对一个Activity页面去编写针对MVP风格的代码. 对于MVP,我的内心有一个问题: 为何这个模式出来后,就能被广大的Android的程序员接受呢? 问了些程序员,他们对于MVP的普遍的认识是:“代

浅谈三层模式

总觉的对三层的理解很肤浅,这几天看了相关的资料,无非谈的就是概括和基本组建附加个小例子!看完了,感觉说的大同小异,自己的理解好像也没什么多大变化,只不过加深了点罢了.不过想想有几天在这方面的思考,还是总结一下吧! 你去饭店吃饭,就遇见了三层,咱们唠唠吃饭这事! 服务员的作用就是给你上菜,收集你的信息,比如来个鱼香肉丝,或是几瓶啤酒,烤串什么的!总之你的一切请求都只是面向服务员的!至于厨师是男的,女的,负责给厨师买材料的采购员,你是没必要知道的.一切为了顾客,就是服务员的宗旨!等哪天这个服务员辞职

RCP开发浅谈之SWT,JFACE

RCP开发浅谈之SWT,JFACE SWT 什么是SWT? SWT全名是Standard Widget Toolkit是一个开源的GUI编程框架,我们每一个java开发者,在学习java开发的时候都会接触到awt以及swing这两个图形库,与awt,swing两个图形库不同,swt的优势体现于底层调用本地的图形库,大大提高了运行速度(损失了一定跨平台性).SWT的一个很重要的一点,一个控件并不是单独存在的,而是存在于父控件中.这样当父控件disposed后,子控件也一定很disposed了.每一

浅谈工厂模式

一个简单的计算器例子来描述工厂模式 Operator公共接口 package com.iss.factory; public interface Operator { public int getResult(int x, int y); } Add.java package com.iss.factory; public class Add implements Operator{ @Override public int getResult(int x, int y) { // TODO A

Android性能优化之利用Rxlifecycle解决RxJava内存泄漏

前言: 其实RxJava引起的内存泄漏是我无意中发现了,本来是想了解Retrofit与RxJava相结合中是如何通过适配器模式解决的,结果却发现了RxJava是会引起内存泄漏的,所有想着查找一下资料学习一下如何解决RxJava引起的内存泄漏,就查到了利用Rxlifecycle开源框架可以解决,今天周末就来学习一下如何使用Rxlifecycle. 引用泄漏的背景: RxJava作为一种响应式编程框架,是目前编程界网红,可谓是家喻户晓,其简洁的编码风格.易用易读的链式方法调用.强大的异步支持等使得R

浅谈MVP实现Android应用层开发

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 背景 之所以要谈这个话题是因为你在开发App时可能会发现,Activity担负的责任非常之重,如果站在MVC框架角度看自己开发的App,一般xml布局文件科Activity的setContentView等充当了View角色,Activity其他代码充当了Controller角色,其他数据来源

浅谈MVP架构及开发模式

Model-View-Presenter(MVP)概述    MVC模式已经出现了几十年了,在GUI领域已经得到了广泛的应用,由于微软ASP.NET MVC Framework的出现,致使MVC一度成为.NET社区的热名话题.作为MVC的变种MVP模式,也已经出现好几年了,在微软模式与实践小组提供的Web Client Software Factory中,给出了实现MVP模式的应用程序最佳实践,本文将试着对这两种实现比较一二.MVC(Model-View-Controller,模型-视图-控制器

Android 设计模式之 浅谈MVP

一.概述 MVP(Model-View-Presenter) 是总所周知MVC模式的一个演变,他们的主要目的都是划分模块职责,降低模块耦合,易测试,提高代码复用,这里主要针对Android平台来简单分析MVP. 1.层级责任 Model:       负责数据的检索,持久化等操作 View:         负责UI的绘制和用户的交互 Presenter: 作为Model和View的中间协调部分,负责两者之间的业务逻辑处理 2.与MVC模式的区别 MVP模式与MVC模式从层级数据流向上来说一个主