Android开发之MVP架构详解

Android开发之MVP架构详解

一、MVP和MVC的一点感悟

  MVP模式估计每个人都了解一点,是从MVC演变而来,随着项目的逐渐变大考虑到产品的维护以及扩展性,MVC的短处逐渐暴露出来,从而让耦合性更低的MVP就得到了人们的青睐。

  对于两则的优缺点以及特性介绍网上有一大堆的博客,此处我也不想再去重复,只是简单记录一下自己的感觉和认识。

  我们在用MVC写项目的时候,随着项目的变大,Activity中的东西会越来越多,Model数据的逻辑处理,VIew的显示全部掺杂在一起,后期的维护和扩展非常费劲,如果是接手别人的项目来维护,那更是让人头大。然而,MVP模式开发的项目看上去就显得让人一目了然,对Activity的任务减轻了不少,结构分明,耦合性更低。

  MVP模式中Activity承担了VIew的角色,Model依然是负责数据的处理,而Model和VIew之间交互的责任则由Presenter来完成,充当一个中介的作用,VIew和Model之间不能之间进行通信。


废话不多说,用代码来说明,Demo很简单,是一个ListView列表,就不截图了。

二、Demo介绍

Demo中VIew层和Model层都使用了接口,


下面是目录结构:


实体类News

public class News {

    private String name;
    private String content;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}


Model 的接口INewsModel

/**
 * model 接口
 */

public interface INewsModel {

    /**
     * 加载数据
     */
    void loadGirls(GirlLoadOnListener listener);

    /**
     * 回调监听,数据接收完成
     */
    interface GirlLoadOnListener {
        //数据传递过来
        void onComplete(List<News> news);
    }

}

 Model的接口实现类

/**
 * Model接口实现类
 */

public class NewsModelImpl implements INewsModel {
    //加载数据
    @Override
    public void loadloadNews(GirlLoadOnListener listener) {
        List<News> dataList = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            News g = new News();
            //内容随便敲的,不重要
            g.setName("案件发is的肌肤" + i);
            g.setContent("撒娇佛is戴假发老司机放假啊考虑实际得分i11" + i);
            dataList.add(g);
        }

        listener.onComplete(dataList);
    }
}


VIew 的接口INewsView

/**
 * VIew层接口
 */

public interface INewsView {

    /**
     * 显示数据
     */
    void showData(List<News> news);

    /***
     * 显示进度
     */
    void showLoading();

    /**
     * 隐藏进度
     */
    void hideLoading();
}

view的接口实现类,其实就是我们的Activity,对于BaseActivity,是为了防止内存溢出使用了泛型,之后介绍。

public class NewsListActivity extends BaseActivity<INewsView, NewsPresenter> implements INewsView {

    private ListView listView;
    private NewsAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.listview);
        //view 和 model绑定
        mPresenter.fetch();
    }

    @Override
    protected NewsPresenter createPresenter() {
        return new NewsPresenter();
    }

    @Override
    public void showData(List<News> news) {
        adapter = new NewsAdapter(NewsListActivity.this, news);
        listView.setAdapter(adapter);
    }

    @Override
    public void showLoading() {
        Toast.makeText(this, "正在加载中...", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void hideLoading() {

    }
}


Presenter 层,BasePresenter中对VIew有引用,为了防止内存溢出使用了弱引用,后面详细介绍。

/**
 * <p>
 * 中间人
 * girls view 和 model 的桥梁
 */

public class NewsPresenter extends BasePresenter<INewsView> {

    private INewsModel mGirlModel = new NewsModelImpl();

    /**
     * view 和model bind
     */
    public void fetch() {
        //显示进度
        getView().showLoading();
        //获取数据
        mGirlModel.loadloadNews(new INewsModel.GirlLoadOnListener() {
            @Override
            public void onComplete(List<News> girls) {
                //显示数据
                getView().showData(girls);
                //隐藏进度
                getView().hideLoading();
            }
        });
    }

}


贴出BaseActivity和 BasePresenter代码

BaseActivity中对Presenter进行了绑定和解除绑定的操作,这是为了避免我们在异步获取网络数据时,用户点击了返回键,此时的Activity就执行了onDestroy方法,但是在Presenter中仍然持有VIew的引用,造成不能及时的回收,从而引起内存溢出。

  所以在onDestroy中进行解绑是很必要的,同时在Presenter中引用的VIew使用弱引用,避免内存溢出。

/**
 * BaseActivity
 */
public abstract class BaseActivity<V, T extends BasePresenter<V>> extends AppCompatActivity {

    protected T mPresenter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //创建presenter
        mPresenter = createPresenter();
        //绑定VIew
        mPresenter.attachView((V) this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //解除绑定
        mPresenter.detachView();
    }

    //创建Presenter
    protected abstract T createPresenter();
}


BasePresenter中对传入的VIew进行了弱引用,VIew一般是我们使用的Activity或Fragment,如果直接进行引用容易造成内存溢出。

/**
 * BasePresenter
 */
public class BasePresenter<T> {

    /**
     * View的弱引用
     */
    protected WeakReference<T> mViewRef;

    /**
     * 关联
     */
    public void attachView(T view) {
        mViewRef = new WeakReference<T>(view);
    }

    /**
     * 解除关联
     */
    public void detachView() {
        if (mViewRef != null) {
            mViewRef.clear();
        }
    }

    /**
     * 得到VIew
     * @return
     */
    protected T getView() {
        return mViewRef.get();
    }

}


demo运行结果就是一个简单的ListVIew。本人菜鸟,欢迎评论指导。





  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值