当前位置: 首页 > news >正文

MVP简单模型搭建【架构】

MVP简介

MVP是一种项目架构设计模式(说白了就是我们产品的一种设计方案) 其实MVP本质 就是将View和Model完全隔离,通过Presenter统一调度管理(Presenter扮演着中介的角色)传统的设计思路是我们直接跟房东谈,效率不高,累。

  • M:Model数据层,一般处理访问网络数据都在这里
  • V:View界面层,与View相关的一些操作都在这里面。View一般代表我们的Activity,Fragment,LinearLayout等等
  • P:Presenter解耦关联层 (关联Model 和 View),可能还要处理一些额外的逻辑操作,数据的处理(比如:数据的筛选等,筛选后给到我们的View去显示)

优点:

1.M层和V层完全分离,只需要通过P,V和P层的桥梁,哪个部分出现问题方便修改。只需要找对应的层级就可以  2.适合多人开发, 代码的复用性强

缺点:

1.接口回掉多,类的数量增多

MVP架构搭建流程

思维构图:

从0到1搭建MVP架构

在里面新建两个接口(Interface),分别取名 BaseView 和 BaseModel,这里定义一些公共方法

public interface BaseView {void showLoading();void hideLoading();void showError();
​
}
​
public interface BaseModel {
​
}

接下来定义一个抽象类,取名 BasePresenter

public abstract class BasePresenter<M, V> {
​protected M mModel;//弱引用的写法,避免内存泄漏。protected WeakReference<V> mView;protected void onAttach(M m, V v) {mView = new WeakReference<>(v);mModel = m;}//检测 V 是否已关联 Pprotected boolean isViewAttached() {return null != mView && null != mView.get();}protected V getView() {return isViewAttached() ? mView.get() : null;}protected void onDetach() {if (null != mView) {mView.clear();mView = null;}}
​
}

该类则用于反射获取指定泛型

public class ReflectUtil {
​public static <T> T getT(Object o, int i) {try {return ((Class<T>) ((ParameterizedType) (o.getClass().getGenericSuperclass())).getActualTypeArguments()[i]).newInstance();} catch (Exception e) {e.printStackTrace();}return null;}
​
}

接下来定义BaseActivity,举一反三BaseFragment同理

public abstract class BaseActivity<T extends BasePresenter, M extends BaseModel> extends AppCompatActivity implements BaseView {
​protected T mPresenter;protected M mModel;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(getLayoutId());//通过反射获取presenter model对象mPresenter = ReflectUtil.getT(this, 0);mModel = ReflectUtil.getT(this, 1);//绑定mPresenter.onAttach(mModel, this);initView();}protected abstract int getLayoutId();protected abstract int initView();@Overridepublic void showLoading() {}@Overridepublic void hideLoading() {}@Overridepublic void showError() {}@Overrideprotected void onDestroy() {super.onDestroy();//解绑mPresenter.onDetach();}
}

创建接口 MvpListener,用于数据从 M 到 V 的层间传递

public interface MvpListener<T> {void onSuccess(T result);
​void onError(String errorMsg);
}

接下来创建一个Contract,来归纳创建view、model、presenter接口,这里可以使用插件mvphelper,省去创建类的步骤

public interface MainContract {interface Model extends BaseModel {void loadDaily(String url, MvpListener<String> listener);}
​interface View extends BaseView {void setData(String s);}abstract class Presenter extends BasePresenter<Model, View> {abstract void loadData(String url);}
}

然后实现这三层,首先是presenter

public class MainPresenter extends MainContract.Presenter {@Overrideprotected void loadData(String url) {MainContract.View mView = getView();if (mView == null) {return;}
​mView.showLoading();//调用model方法,获取网络请求回调结果mModel.loadDaily(url, new MvpListener<String>() {@Overridepublic void onSuccess(String result) {mView.hideLoading();mView.setData(result);}@Overridepublic void onError(String errorMsg) {mView.hideLoading();mView.showError();}});}
}

接下来是model,我这里网络请求使用的okgo,这个根据自己喜好用什么都一样,需要在成功跟失败的回调里去调用自定义的mvplistener

public class MainModel implements MainContract.Model {@Overridepublic void loadDaily(String url, MvpListener<String> listener) {//这里执行网络请求操作OkGo.<String>get(url).execute(new StringCallback() {@Overridepublic void onSuccess(Response<String> response) {listener.onSuccess(response.body());}
​@Overridepublic void onError(Response<String> response) {super.onError(response);listener.onError(response.body());}});}
}

最后是view,也就是我们的activity

public class MainActivity extends BaseActivity<MainPresenter, MainModel> implements MainContract.View {
​private static final Locale LOCALE = Locale.CHINA;@Overrideprotected int getLayoutId() {return R.layout.activity_main;}@Overrideprotected void initView() {mPresenter.loadData("http://news.at.zhihu.com/api/4/news/before/" + format(new Date(), "yyyyMMdd"));}
​​@Overridepublic void setData(String s) {Toast.makeText(this, "请求结果" + s, Toast.LENGTH_SHORT).show();}public static String format(Date date, String s) {return new SimpleDateFormat(s, LOCALE).format(date);}
}

本文意在搭建mvp,就不去做数据列表展示了,在这里做了一个toast,贴上成功的截图

全文介绍了MVP的介绍及原理;再到0至1的搭建过程;更多架构学习技术,可参考《Android核心技术手册 》点击查看。需要的获取一下。

总结

最后,到这里mvp框架就搭建完毕了,总结一下实现过程

  1. 创建baseview、basemodel、basepresenter、baseactivity基类
  2. 创建contract类创建view、model、presenter内部类编写抽象方法
  3. 创建view、model、presenter实现类

相关文章:

MVP简单模型搭建【架构】

MVP简介 MVP是一种项目架构设计模式&#xff08;说白了就是我们产品的一种设计方案&#xff09; 其实MVP本质 就是将View和Model完全隔离&#xff0c;通过Presenter统一调度管理&#xff08;Presenter扮演着中介的角色&#xff09;传统的设计思路是我们直接跟房东谈&#xff0…...

若依ruoyi框架实现目录树与查询页面联动

目录1、业务场景2、前端api.js修改index.vue修改template修改script修改3、后端controllerserviceimpldomainentitytreeselect1、业务场景 后管页面实现目录数与查询页面的联动&#xff0c;类似若依框架用户管理页面。 2、前端 api.js修改 在原有的js文件里配置目录树的查…...

Laravel框架学习笔记——Laravel环境配置及安装(Ubuntu20.04为例)

目录引言1、安装Nginx2、安装PHP3、安装Composer4、搭建Laravel框架项目5、修改Nginx映射6、安装MySQL引言 好久没写博客了&#xff0c;因为个人需要&#xff0c; 所以要涉及到Laravel框架的学习&#xff0c;所以会出一系列的关于PHP的Laravel框架学习笔记&#xff0c;希望能够…...

模拟百度翻译-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)

【案例6-5】 模拟百度翻译 【案例介绍】 1.任务描述 大家对百度翻译并不陌生&#xff0c;本案例要求编写一个程序模拟百度翻译。用户输入英文之后搜索程序中对应的中文&#xff0c;如果搜索到对应的中文就输出搜索结果&#xff0c;反之给出提示。本案例要求使用Map集合实现英…...

自然语言处理(NLP)之求近义词和类比词<MXNet中GloVe和FastText的模型使用>

这节主要就是熟悉MXNet框架中的两种模型&#xff1a;GloVe和FastText的模型(词嵌入名称)&#xff0c;每个模型下面有很多不同的词向量&#xff0c;这些基本都来自wiki维基百科和twitter推特这些子集预训练得到的。我们只需要导入mxnet.contrib中的text模块即可&#xff0c;这里…...

2023年CDGA考试-第13章-数据质量(含答案)

2023年CDGA考试-第13章-数据质量(含答案) 单选题 1.在导致数据质量问题的常见原因中关于数据输入问题以下描述正确的是: A.数据采集端缺乏数据质量管控 B.相同字段重复设计导致数据不一致 C.缺乏数据采集规范的制定 D.所有描述都正确 答案 D 2.数据质量计划应将其范围限…...

ASEMI高压MOS管ASE65R330参数,ASE65R330图片

编辑-Z ASEMI高压MOS管ASE65R330参数&#xff1a; 型号&#xff1a;ASE65R330 漏极-源极电压&#xff08;VDS&#xff09;&#xff1a;650V 栅源电压&#xff08;VGS&#xff09;&#xff1a;20V 漏极电流&#xff08;ID&#xff09;&#xff1a;12.5A 功耗&#xff08;P…...

LeetCode动态规划经典题目(九):子序列、子数组问题

目录 31. LeetCode674. 最长连续递增序列 32. LeetCode18. 最长重复子数组 33. LeetCode1143. 最长公共子序列 34. LeetCode1035. 不相交的线 35. LeetCode53. 最大子数组和 36. LeetCode392.判断子序列 37. LeetCode115. 不同的子序列 38. LeetCode583. 两个字符串的删…...

如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响

SCI的写作和发表是科研人提升自身实力和实现自己价值的必要途径。“如何利用有限的数据发表更多的SCI论文&#xff1f;”是我们需要解决的关键问题。软件应用只是过程和手段&#xff0c;理解事件之间的内在逻辑和寻找事物之间的内在规律才是目的。如何利用有限的数据发表更多的…...

六【 SpringMVC框架】

一 SpringMVC框架 目录一 SpringMVC框架1.什么是MVC2.SpringMVC概述3.SpringMVC常见开发方式4.SpringMVC执行流程5.SpringMVC核心组件介绍6.快速构建Spring MVC程序✅作者简介&#xff1a;Java-小白后端开发者 &#x1f96d;公认外号&#xff1a;球场上的黑曼巴 &#x1f34e;个…...

【BBuf的CUDA笔记】八,对比学习OneFlow 和 FasterTransformer 的 Softmax Cuda实现

0x1. OneFlow/FasterTransformer SoftMax CUDA Kernel 实现学习 这篇文章主要学习了oneflow的softmax kernel实现以及Faster Transformer softmax kernel的实现&#xff0c;并以个人的角度分别解析了原理和代码实现&#xff0c;最后对性能做一个对比方便大家直观的感受到onefl…...

python 类对象的析构释放代码演示

文章目录一、类的构造函数与析构函数二、代码演示1. 引用的更迭2. 只在函数内部的类对象三、函数内部返回的类对象1. 使用全局变量 引用 函数内部的类对象一、类的构造函数与析构函数 init 函数是python 类的构造函数&#xff0c;在创建一个类对象的时候&#xff0c;就会自动调…...

Hadoop Shell常用命令

Hadoop Shell命令在管理HDFS的时候还是比较常用的&#xff0c;Hadoop Shell命令与shell命令极为相似&#xff0c;但是方便查询&#xff0c;在这里总结分享&#xff0c;大家enjoy~~ 1&#xff0c;cat 语法格式&#xff1a;hadoop fs -cat URI [URI …] 含义&#xff1a;将路径…...

Android中级——色彩处理和图像处理

色彩处理 通过色彩矩阵处理 色彩矩阵介绍 图像的RGBA可拆分为一个4行5列的矩阵和5行1列矩阵相乘 其中4行5列矩阵即为ColorMatrix&#xff0c;可通过调整ColorMatrix间接调整RGBA 第一行 abcde 决定新的 R第二行 fghij 决定新的 G第三行 klmno 决定新的 G第四行 pqrst 决定新…...

C++类和对象:类的定义、类对象的存储、this指针

目录 一. 对于面向过程和面向对象的认识 二. 类 2.1 struct关键字定义类 2.1.1 C语言中的struct关键字 2.1.2 C中的struct关键字 2.2 class关键字 2.1 使用class关键字定义类 三. 类的访问限定及封装 3.1 类的访问权限及访问限定符 3.1.1 访问权限 3.1.2 访问限定…...

代码随想录算法训练营第三十九天 | 62.不同路径,63. 不同路径 II

一、参考资料不同路径https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84.html 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ve4y1x7Eu不同路径 IIhttps://programmercarl.com/0063.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84II.htmlhttps://progr…...

数据库复习3

一. 简答题&#xff08;共1题&#xff0c;100分&#xff09; 1. (简答题) 存在数据库test&#xff0c;数据库中有如下表&#xff1a; 1.学生表 Student(Sno,Sname,Sage,Ssex) --Sno 学号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 主键Sno 2.教师表 Teacher(Tno,Tname) --T…...

顺序表的增删查改

数据结构 是数据存储的方式&#xff0c;对于不同的数据我们要采用不同的数据结构。就像交通运输&#xff0c;选用什么交通工具取决于你要运输的是人还是货物&#xff0c;以及它们的数量。 顺序存储结构 包括顺序表、链表、栈和队列等。 例如腾讯QQ中的好友列表&#xff0c;…...

jupyter matplotlib中文乱码解决

中文乱码可能有两种情况 1. matplotlib里面有中文字体 2. 没有中文字体 查看是否有中文字体: # 查询当前系统所有字体 from matplotlib.font_manager import FontManager import subprocessmpl_fonts = set(f.name for f in FontManager().ttflist)print(all font list get f…...

Smtplib之发邮件模块

目录 创建Smtp对象 Smtp类中的方法 MIME MIMEBase MIMEBase MIMEMultipart MIMEApplication MIMEAudio MIMEImage MIMEText 实例 texthtml格式 发送带图片附件的邮件 发送带附件的邮件 含多种格式 SMTP模块 SMTP 简单传输协议&#xff0c;它是一组用于由源…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

镜像里切换为普通用户

如果你登录远程虚拟机默认就是 root 用户&#xff0c;但你不希望用 root 权限运行 ns-3&#xff08;这是对的&#xff0c;ns3 工具会拒绝 root&#xff09;&#xff0c;你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案&#xff1a;创建非 roo…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...