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框架就搭建完毕了,总结一下实现过程
- 创建baseview、basemodel、basepresenter、baseactivity基类
- 创建contract类创建view、model、presenter内部类编写抽象方法
- 创建view、model、presenter实现类
相关文章:
MVP简单模型搭建【架构】
MVP简介 MVP是一种项目架构设计模式(说白了就是我们产品的一种设计方案) 其实MVP本质 就是将View和Model完全隔离,通过Presenter统一调度管理(Presenter扮演着中介的角色)传统的设计思路是我们直接跟房东谈࿰…...
若依ruoyi框架实现目录树与查询页面联动
目录1、业务场景2、前端api.js修改index.vue修改template修改script修改3、后端controllerserviceimpldomainentitytreeselect1、业务场景 后管页面实现目录数与查询页面的联动,类似若依框架用户管理页面。 2、前端 api.js修改 在原有的js文件里配置目录树的查…...
Laravel框架学习笔记——Laravel环境配置及安装(Ubuntu20.04为例)
目录引言1、安装Nginx2、安装PHP3、安装Composer4、搭建Laravel框架项目5、修改Nginx映射6、安装MySQL引言 好久没写博客了,因为个人需要, 所以要涉及到Laravel框架的学习,所以会出一系列的关于PHP的Laravel框架学习笔记,希望能够…...
模拟百度翻译-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)
【案例6-5】 模拟百度翻译 【案例介绍】 1.任务描述 大家对百度翻译并不陌生,本案例要求编写一个程序模拟百度翻译。用户输入英文之后搜索程序中对应的中文,如果搜索到对应的中文就输出搜索结果,反之给出提示。本案例要求使用Map集合实现英…...
自然语言处理(NLP)之求近义词和类比词<MXNet中GloVe和FastText的模型使用>
这节主要就是熟悉MXNet框架中的两种模型:GloVe和FastText的模型(词嵌入名称),每个模型下面有很多不同的词向量,这些基本都来自wiki维基百科和twitter推特这些子集预训练得到的。我们只需要导入mxnet.contrib中的text模块即可,这里…...
2023年CDGA考试-第13章-数据质量(含答案)
2023年CDGA考试-第13章-数据质量(含答案) 单选题 1.在导致数据质量问题的常见原因中关于数据输入问题以下描述正确的是: A.数据采集端缺乏数据质量管控 B.相同字段重复设计导致数据不一致 C.缺乏数据采集规范的制定 D.所有描述都正确 答案 D 2.数据质量计划应将其范围限…...
ASEMI高压MOS管ASE65R330参数,ASE65R330图片
编辑-Z ASEMI高压MOS管ASE65R330参数: 型号:ASE65R330 漏极-源极电压(VDS):650V 栅源电压(VGS):20V 漏极电流(ID):12.5A 功耗(P…...
LeetCode动态规划经典题目(九):子序列、子数组问题
目录 31. LeetCode674. 最长连续递增序列 32. LeetCode18. 最长重复子数组 33. LeetCode1143. 最长公共子序列 34. LeetCode1035. 不相交的线 35. LeetCode53. 最大子数组和 36. LeetCode392.判断子序列 37. LeetCode115. 不同的子序列 38. LeetCode583. 两个字符串的删…...
如何利用有限的数据发表更多的SCI论文?——利用ArcGIS探究环境和生态因子对水体、土壤和大气污染物的影响
SCI的写作和发表是科研人提升自身实力和实现自己价值的必要途径。“如何利用有限的数据发表更多的SCI论文?”是我们需要解决的关键问题。软件应用只是过程和手段,理解事件之间的内在逻辑和寻找事物之间的内在规律才是目的。如何利用有限的数据发表更多的…...
六【 SpringMVC框架】
一 SpringMVC框架 目录一 SpringMVC框架1.什么是MVC2.SpringMVC概述3.SpringMVC常见开发方式4.SpringMVC执行流程5.SpringMVC核心组件介绍6.快速构建Spring MVC程序✅作者简介:Java-小白后端开发者 🥭公认外号:球场上的黑曼巴 🍎个…...
【BBuf的CUDA笔记】八,对比学习OneFlow 和 FasterTransformer 的 Softmax Cuda实现
0x1. OneFlow/FasterTransformer SoftMax CUDA Kernel 实现学习 这篇文章主要学习了oneflow的softmax kernel实现以及Faster Transformer softmax kernel的实现,并以个人的角度分别解析了原理和代码实现,最后对性能做一个对比方便大家直观的感受到onefl…...
python 类对象的析构释放代码演示
文章目录一、类的构造函数与析构函数二、代码演示1. 引用的更迭2. 只在函数内部的类对象三、函数内部返回的类对象1. 使用全局变量 引用 函数内部的类对象一、类的构造函数与析构函数 init 函数是python 类的构造函数,在创建一个类对象的时候,就会自动调…...
Hadoop Shell常用命令
Hadoop Shell命令在管理HDFS的时候还是比较常用的,Hadoop Shell命令与shell命令极为相似,但是方便查询,在这里总结分享,大家enjoy~~ 1,cat 语法格式:hadoop fs -cat URI [URI …] 含义:将路径…...
Android中级——色彩处理和图像处理
色彩处理 通过色彩矩阵处理 色彩矩阵介绍 图像的RGBA可拆分为一个4行5列的矩阵和5行1列矩阵相乘 其中4行5列矩阵即为ColorMatrix,可通过调整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 视频讲解: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
一. 简答题(共1题,100分) 1. (简答题) 存在数据库test,数据库中有如下表: 1.学生表 Student(Sno,Sname,Sage,Ssex) --Sno 学号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 主键Sno 2.教师表 Teacher(Tno,Tname) --T…...
顺序表的增删查改
数据结构 是数据存储的方式,对于不同的数据我们要采用不同的数据结构。就像交通运输,选用什么交通工具取决于你要运输的是人还是货物,以及它们的数量。 顺序存储结构 包括顺序表、链表、栈和队列等。 例如腾讯QQ中的好友列表,…...
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 简单传输协议,它是一组用于由源…...
PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
32位寻址与64位寻址
32位寻址与64位寻址 32位寻址是什么? 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元(地址),其核心含义与能力如下: 1. 核心定义 地址位宽:CPU或内存控制器用32位…...
Java多线程实现之Runnable接口深度解析
Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...
Axure Rp 11 安装、汉化、授权
Axure Rp 11 安装、汉化、授权 1、前言2、汉化2.1、汉化文件下载2.2、windows汉化流程2.3、 macOs汉化流程 3、授权 1、前言 Axure Rp 11官方下载链接:https://www.axure.com/downloadthanks 2、汉化 2.1、汉化文件下载 链接: https://pan.baidu.com/s/18Clf…...
iOS 项目怎么构建稳定性保障机制?一次系统性防错经验分享(含 KeyMob 工具应用)
崩溃、内存飙升、后台任务未释放、页面卡顿、日志丢失——稳定性问题,不一定会立刻崩,但一旦积累,就是“上线后救不回来的代价”。 稳定性保障不是某个工具的功能,而是一套贯穿开发、测试、上线全流程的“观测分析防范”机制。 …...
02-性能方案设计
需求分析与测试设计 根据具体的性能测试需求,确定测试类型,以及压测的模块(web/mysql/redis/系统整体)前期要与相关人员充分沟通,初步确定压测方案及具体的性能指标QA完成性能测试设计后,需产出测试方案文档发送邮件到项目组&…...
Async-profiler 内存采样机制解析:从原理到实现
引言 在 Java 性能调优的工具箱中,async-profiler 是一款备受青睐的低开销采样分析器。它不仅能分析 CPU 热点,还能精确追踪内存分配情况。本文将深入探讨 async-profiler 实现内存采样的多种机制,结合代码示例解析其工作原理。 为什么需要内…...
