什么是MVP模式?
     这个MVP可不是腾讯游戏《王者荣耀》中的MVP。我们今天要讨论的MVP其实同MVC一样,是一种编程模式和思想,也许更准确地讲是一种架构。

MVP和MVC的区别
     提到MVP模式,大家自然避免不了要和我们以前常用的MVC模式进行对比。关于MVP和MVC的区别,此处我们就不重复造轮子了,给大家推荐两篇文章:

两张图看懂Android开发中MVC与MVP的区别
Android中MVP模式讲解及实践

MVP模式的介绍
先上两张示例图(网上的图大同小异,都一样)

mvp耦合图示:

mvp使用交互流程图示:

MVP 全称是Model - View - Presenter ,是模型(model)-视图(view)-呈现器(presenter)的缩写。

Model:业务逻辑和数据处理(数据库存储操作,网络数据请求,复杂算法,耗时操作)。

View : 对应于Activity,负责View的绘制以及与用户交互。

Presenter:负责完成View于Model间的交互 (有一点还需要注意,presenter是双向绑定的关系,因此,在设计的时候就要注意接口和抽象的使用,尽可能的降低代码的耦合度,这也是mvp的宗旨)。

MVP模式使用示例佐证
下面参照网上有个比较通俗的示例,来讲述下MVP 模式的使用。
以最常用的网络数据请求为例。
先来明确下MVP中各个环节的责任划分,然后照此进行代码布局。

责任划分:
Model: 定义并实现获取数据操作(如数据库读取、网络加载)的接口
View: 定义并在Activity,Fragment等中实现用于界面处理(初始化,数据展示)的接口
Presenter: 定义用于调用Model中的数据请求方法的接口,实现此接口,并实现Model中定义的数据请求的接口

项目结构:

Step 1/编写Model逻辑:

数据请求接口(如数据库读取、网络加载)的定义:

/*** Model层接口---实现该接口的类负责实际的获取数据操作,如数据库读取、网络加载*/
public interface IModel {void getData(Model.LoadDataCallback callback);
}

数据请求接口的实现:

/*** 实现IModel接口,负责实际的数据获取操作(数据库读取,网络加载等),然后通过自己的接口(LoadDataCallback)反馈出去*/
public class Model implements IModel {@Overridepublic void getData(final LoadDataCallback callback) {//数据获取操作,如数据库查询、网络加载等new Thread() {@Overridepublic void run() {try {//模拟耗时操作Thread.sleep(3000);//获取到了数据String data = "我是获取到的数据";//将获取的数据通过接口反馈出去callback.success(data);} catch (InterruptedException e) {e.printStackTrace();//获取数据失败的回调callback.failure();}}}.start();}/**** 用于回传请求的数据的回传*/public interface LoadDataCallback {void success(String taskId);void failure();}
}

Step 2/编写View逻辑:
定义用于界面处理(初始化,数据展示)的接口

/*** View层接口---执行各种UI操作,定义的方法主要是给Presenter中来调用的*/
public interface IView {void showLoadingProgress(String message);void showData(String text);
}

在Activity,Fragment等中对接口的实现:

/*** 实现IView接口并实现各种UI操作的方法(其他的业务逻辑在Presenter中进行操作)*/
public class ViewActivity extends AppCompatActivity implements IView {private Button mBtnShowToast;private TextView mText;private MyHandler mHandler = new MyHandler(ViewActivity.this);private IPresenter mPresenter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_mvp);//实例化Presenter,并将实现了IView接口的类传入进去mPresenter = new Presenter(ViewActivity.this);mBtnShowToast = findViewById(R.id.btn_show_toast);mText = findViewById(R.id.text);mBtnShowToast.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//通过Presenter来实现业务逻辑操作,View层只负责UI相关操作mPresenter.loadData();}});}@Overridepublic void showLoadingProgress(final String message) {mHandler.post(new Runnable() {@Overridepublic void run() {mText.setText(message);}});}@Overridepublic void showData(final String text) {mHandler.post(new Runnable() {@Overridepublic void run() {mText.setText(text);}});}private static class MyHandler extends Handler {//弱引用,防止内存泄露WeakReference<ViewActivity> weakReference;public MyHandler(ViewActivity activity) {this.weakReference = new WeakReference<ViewActivity>(activity);}@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1:weakReference.get().mText.setText(msg.what);break;}}}
}

Step 3/编写presenter逻辑(重点关注)
presenter层很重要,为什么这样说呢?
因为MVP模式中,View和Model是不直接交互的,而是通过presenter这个纽带来进行交互-----------View通过presenter对象来调用Model中数据请求的接口,而Model中数据请求的结果会通过presenter中定义的接口回调给presenter,然后presenter在通知给View。

定义用于调用Model中的数据请求方法的接口:
具体实现:

/*** Presenter层接口---控制Model层的数据操作及调用View层的UI操作来完成“中间人”工作*/
public interface IPresenter {void loadData();}

定义用于调用Model中的数据请求方法的接口,实现此接口,并实现M中定义的数据请求的接口

/*** Presenter层接口---控制Model层的数据操作及调用View层的UI操作来完成“中间人”工作.* 用于model和view的相关方法的调用*/
public class Presenter implements IPresenter, Model.LoadDataCallback {private final IView mView;private final Model mModel;public Presenter(IView view) {mView = view;mModel = new Model();}@Overridepublic void loadData() {mView.showLoadingProgress("加载数据中");mModel.getData(Presenter.this);}@Overridepublic void success(String data) {mView.showData(data);}@Overridepublic void failure() {}
}

大家要多看,多试验,最重要的是理解思路,理解思路,理解思路。重要的事情说三遍。Google官方的MVP代码大家可以去研读一下,是同一个模式,只不过它把好多接口集成在一个接口文件中,防止代码碎片化,大家研读时记住这一点,就不会困惑了。

最后附上Google MVP的代码地址:

https://github.com/googlesamples/android-architecture/tree/todo-mvp/

————————————————
版权声明:本文为CSDN博主「游走的大千世界的烤腰子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhangqunshuai/article/details/82562801

MVP模式使用示例详解相关推荐

  1. android mvp模式例子_Android中mvp模式使用实例详解

    MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.作为一种新的模式,MVP与MVC有着一 ...

  2. android中的mvp模式怎么定义,详解MVP模式在Android开发中的应用

    一.MVP介绍 随着UI创建技术的功能日益增强,UI层也履行着越来越多的职责.为了更好地细分视图(View)与模型(Model)的功能,让View专注于处理数据的可视化以及与用户的交互,同时让Mode ...

  3. java网络编程阻塞_Java网络编程由浅入深三 一文了解非阻塞通信的图文代码示例详解...

    本文详细介绍组成非阻塞通信的几大类:Buffer.Channel.Selector.SelectionKey 非阻塞通信的流程ServerSocketChannel通过open方法获取ServerSo ...

  4. php mysql 正则表达式_mysql正则表达式(Regexp)的示例详解

    MySQL支持基于正则表达式和REGEXP运算符的另一种模式匹配操作.(相关推荐:<MySQL教程>) 1.它提供了强大而灵活的模式匹配,可以帮助我们为数据库系统实现power搜索实用程序 ...

  5. rcs开机启动mysql_linux添加开机自启动脚本示例详解-阿里云开发者社区

    linux添加开机自启动脚本示例详解 double2li 2017-04-14 1652浏览量 简介: linux下(以RedHat为范本)添加开机自启动脚本有两种方法,先来简单的;一.在/etc/r ...

  6. mysql讲事物写到数据库_CookBook/1-MySQL数据库读写锁示例详解、事务隔离级别示例详解.md at master · Byron4j/CookBook · GitHub...

    MySQL数据库读写锁示例详解.事务隔离级别示例详解 锁 性能分:乐观(比如使用version字段比对,无需等待).悲观(需要等待其他事务) 乐观锁,如它的名字那样,总是认为别人不会去修改,只有在提交 ...

  7. python音频转数组_python音频处理的示例详解

    准备工作: 首先,我们需要 import 几个工具包,一个是 python 标准库中的 wave 模块,用于音频处理操作,另外两个是 numpy 和 matplot,提供数据处理函数. 一:读取本地音 ...

  8. RabbitMQ--交换器类型/队列模式--使用/教程/详解

    原文网址:RabbitMQ--交换器类型/队列模式--使用/教程/详解_IT利刃出鞘的博客-CSDN博客 简介 本文介绍RabbitMQ的交换器类型和队列模式. 本内容也是Java后端面试常见的问题. ...

  9. python录音详解_python音频处理的示例详解

    准备工作: 首先,我们需要 import 几个工具包,一个是 python 标准库中的 wave 模块,用于音频处理操作,另外两个是 numpy 和 matplot,提供数据处理函数. 一:读取本地音 ...

最新文章

  1. 2022-2028年中国耐二甲醚橡胶密封材料行业市场全景调研及发展趋势分析报告
  2. H.264 Video Codec速度和质量
  3. Spring+SpringMVC+shiro+mysql(一)
  4. (0073)iOS开发之核心动画高级技巧
  5. HarmonyOS之跨设备分布式应用调试
  6. linux 下批量压缩文件
  7. python 显示gif_使用tkinter显示动态gif
  8. android ogg 播放器,android如何让自己开发的播放器成为可供文件选择的播放器
  9. 适合外贸建站的vatage主题教程
  10. Delayed Project(下)
  11. 精品微信小程序ssm电影院购票+后台管理系统|前后分离VUE
  12. Visual Studio 2022下载安装及使用教程
  13. html文字用竖线隔开,inline+padding技巧:间隔符(分割线)与文字高度不一致,间隔竖线高度缩短方法...
  14. iOS15.6和iOS15.5哪个更省电 iOS15.6建不建议升级
  15. 千亿元宇宙市场,Soul、映客的新动力
  16. 服务器所属文件变成nobody,NFS(expirtfs命令,NFS客户端创建新文件所属组和所属主都为nobody)(示例代码)...
  17. 检查 Windows 版本与 Windows 更新
  18. 佳佳的筷子 Chopsticks
  19. Android 折叠屏技术发展与适配
  20. Python-密码爆破

热门文章

  1. Oracle11g:用户频繁锁定并且解锁后,不允许登录
  2. 在Linux中修改打开文件数量和进程数量限制的3种方法
  3. mPaas容器跳到原生页面使用popWindow返回后获取不到返回数据问题分析
  4. Java 向量点积计算
  5. redis3.2.100在windows不支持daemonize命令后台启动
  6. KNN算法的sklearn实践
  7. Verasonics系统用户主要研究方向及部分参考文献
  8. 屏蔽HOME键(4.0以下)
  9. 笔试题——尤雨溪的10道题
  10. 文档笔记----nodejs菜鸟教程