Android开发MVP架构记录

Android开发MVP架构记录

安卓的MVP(Model-View-Presenter)架构是一种常见的软件设计模式,用于帮助开发者组织和分离应用程序的不同组成部分。MVP架构的目标是将应用程序的业务逻辑(Presenter)、用户界面(View)和数据模型(Model)解耦,从而提高代码的可维护性、可测试性和可扩展性。

下面是MVP架构中各个组成部分的角色和职责:

  1. Model(模型):Model表示应用程序的数据模型层,负责处理数据的获取、存储、操作以及业务逻辑的处理。它可以是数据库、网络请求、文件系统等。Model不直接与View交互,而是通过Presenter进行通信。

  2. View(视图):View是用户界面层,负责展示数据和接收用户的输入操作。它通常是Activity、Fragment或者自定义的View组件。View需要将用户的操作传递给Presenter,并将Presenter返回的数据展示给用户。

  3. Presenter(展示器):Presenter是连接Model和View的桥梁,负责处理业务逻辑和控制数据流。它接收用户的操作请求并根据需要从Model中获取数据,然后将处理结果传递给View进行展示。Presenter不直接操作View,而是通过定义的接口进行交互。

MVP架构的优点包括:

  • 分离关注点:MVP架构将业务逻辑、数据模型和用户界面分离,使得各自的责任更加清晰,易于维护和修改。
  • 可测试性:由于Presenter和Model是独立的组件,并且没有直接依赖于Android Framework,因此可以更容易地进行单元测试。
  • 可扩展性:通过定义接口和契约类(Contract)来规范组件之间的交互,可以方便地进行功能扩展和替换。

一个安卓项目结构示例:

image-20230925185446075

  1. activity:存放activity页面

  2. adapter:存放适配器,配合RecycleView展示页面

  3. base:存放基类,如:BaseActivity、BaseFargment,将一些公共方法写在基类中

  4. entity:存放实体类,或一些数据结构对象

  5. essential:存放接口类,里面的接口定义了一系列规范,是程序的核心

    IView接口类:是(Activity或Fragment)视图的接口,定义视图有哪些执行方法,每个方法的具体实现中会对UI进行操作。

    //所有IView的接口
    public interface IView {//登录页接口规范interface LoginView extends BaseView{void successLogin();void failLogin();}//发现页接口规范interface ExploreView extends BaseView{void showBlogs(List<Blog> blogList);}//其他视图接口规范
    }

    IPrensenter接口类:是Prensenter的接口,定义了Presenter的行为

    //所有Presenter的接口
    public interface IPresenter {//登录presenter接口interface login extends BasePresenter {void checkLogin(String body);}//发现prensenter接口interface exploreReq extends BasePresenter {void getPageBlogs(int page,int limit);}//其他presenter的接口
    }
    
  6. fragment:存放fragment页面

  7. presenter:存放prensenter实现类

    image-20230925190614971

    public class ExplorePresenter implements IPresenter.exploreReq {IView.ExploreView exploreView;public ExplorePresenter(IView.ExploreView exploreView) {this.exploreView = exploreView;}@Overridepublic BaseView getBase() {return exploreView;}//观察者Observer<List<Blog>> blogObserver = new Observer<List<Blog>>() {@Overridepublic void onSubscribe(Disposable d) {}@Overridepublic void onNext(List<Blog> blogList) {exploreView.showBlogs(blogList);}@Overridepublic void onError(Throwable e) {}@Overridepublic void onComplete() {}};@Overridepublic void getPageBlogs(int page, int limit) {ApiServiceFactory.getInstance().getPageBlogs(page, limit).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(blogObserver);}}
  8. retrofit:网络请求框架,存放相关类。

    image-20230925190803532

    ApiService类

    //retrofit定义接口
    public interface ApiService {@GET("api/getBlog/")Observable<List<Blog>> getPageBlogs(@Query("page") int page, @Query("limit") int limit);@POST("api/login")Observable<Result<User>> login(@Body String body);// 添加其他接口方法...
    }
    

    ApiServiceFactory

    public class ApiServiceFactory {private static final String BASE_URL = "http://10.152.177.187:8180/";private static OkHttpClient okHttpClient;private static Retrofit retrofit;private static ApiService apiService;private static final long cacheSize = 1024 * 1024 * 15;// 缓存文件最大限制大小20Mprivate static String cacheDirectory = Environment.getExternalStorageDirectory() + "/aop"; // 设置缓存文件路径private static Cache cache = new Cache(new File(cacheDirectory), cacheSize);  //public static ApiService getInstance() {if (apiService == null) {if (retrofit == null) {retrofit = createRetrofit();}apiService = retrofit.create(ApiService.class);}return apiService;}private static Retrofit createRetrofit() {return new Retrofit.Builder().baseUrl(BASE_URL).client(getOkHttpClient()).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();}private static OkHttpClient getOkHttpClient() {if (okHttpClient == null) {OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.connectTimeout(30, TimeUnit.SECONDS); // 设置连接超时时间builder.writeTimeout(30, TimeUnit.SECONDS);// 设置写入超时时间builder.readTimeout(30, TimeUnit.SECONDS);// 设置读取数据超时时间builder.retryOnConnectionFailure(true);// 设置进行连接失败重试
    //            builder.addNetworkInterceptor(getInterceptor());if (Constants.ISDEBUG) {builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));//拦截器}builder.cache(cache);// 设置缓存,cacheDir和cacheSize需要根据实际情况设置okHttpClient = builder.build();}return okHttpClient;}private static Interceptor getInterceptor() {// 返回你自定义的拦截器,如果没有特殊需求可以返回nullreturn null;}
    }
    

    Result类:规范返回数据结构类,使所有的返回数据结构为result类,真正数据存放在result.data中,这样就规范了返回结果。

    //统一返回数据结构
    public class Result<T> {private String code;private String msg;private T data; //T表示泛型public String getCode() {return code;}public String getMsg() {return msg;}public T getData() {return data;}public void setCode(String code) {this.code = code;}public void setMsg(String msg) {this.msg = msg;}public void setData(T data) {this.data = data;}public Result() {}public Result(T data) {this.data = data;}public static Result success() {Result result = new Result<>();result.setCode("200");result.setMsg("成功");return result;}public static <T> Result<T> success(T data) {Result<T> result = new Result<>(data);result.setCode("0");result.setMsg("成功");return result;}public static Result error(String code, String msg) {Result result = new Result();result.setCode(code);result.setMsg(msg);return result;}
    }
    
  9. util:存放工具类、常量类、全局变量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/141764.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

CockroachDB集群部署

CockroachDB集群部署 1、CockroachDB简介 CockroachDB(有时简称为CRDB)是一个免费的、开源的分布式 SQL 数据库&#xff0c;它建立在一个事务性和强一致性的键 值存储之上。它由 PebbleDB(一个受 RocksDB/leveldb 启发的 K/B 存储库)支持&#xff0c;并使用 Raft 分布式共识…

2023-Chrome插件推荐

Chrome插件推荐 一键管理扩展 链接 https://chromewebstore.google.com/detail/lboblnfejcmcaplhnbkkfcienhlhpnni 介绍 一键开启、禁用Chrome插件。 Checker Plus for Gmail™ 链接 https://jasonsavard.com/zh-CN/Checker-Plus-for-Gmail https://chromewebstore.goo…

VS2019创建GIt仓库时剔除文件或目录

假设本地有解决方案“SomeSolution” 1、首先”团队资源管理器“-“创建Git存储库”&#xff0c;选择“仅限本地”、“创建” VS会在解决方案目录下自动生成.gitattributes、.gitignore 2、编辑gitignore&#xff0c;直接拖到VS里或者用记事本打开。添加要剔除的文件或文件夹…

【算法练习Day3】 移除链表元素设计链表反转链表

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;练题 &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 文章目录 移除链表元素其他问题 设…

Xilinx FPGA 7系列 GTX/GTH Transceivers (4) Aurora 8b10b 递增数收发验证

第一节:Xilinx FPGA 7系列 GTX/GTH Transceivers (1)–了解了GTX硬件的基础知识 第二节:IBERT GTX --通过Ibert IP测试链路通信 第三节:aurora 8b10b single lane 4byte–学习官方历程 递增数验证 自行编写data_gen和data_check 验证aurora 8b10b SFP 1.25G 收发正确。 组…

如何使用show profile 查看sql的执行周期

修改配置文件/etc/my.cnf 新增一行&#xff1a;query_cache_type1 重启mysql 先开启 show variables like %profiling%; set profiling1;select * from xxx ;show profiles; #显示最近的几次查询show profile cpu,block io for query 编号 #查看程序的执行步骤

第1篇 目标检测概述 —(2)目标检测算法介绍

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。目标检测算法是一种计算机视觉算法&#xff0c;用于在图像或视频中识别和定位特定的目标物体。常见的目标检测算法包括传统的基于特征的方法&#xff08;如Haar特征和HOG特征&#xff09;以及基于深度学习的方法&#xff0…

C++ - map 和 set 的模拟实现 - 红黑树当中的仿函数 - 红黑树的迭代器实现

简单了解map 和 set 的实现 首先我们要知道&#xff0c;map 和 set 的底层就是 红黑树&#xff0c;但是 STL 当中 &#xff0c;map 和 set 并不是我们想象的&#xff0c;直接使用一个 pair 对象来存储一个 key-value 或者 是 一个 key。具体如下所示&#xff1a; set&#xff…

基于微信小程序的线上教育课程付费商城(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

MATLAB APP纯小白入门 两数相加

万事开头难&#xff0c;最怕第一次。使用matlab APP 实现两数求和&#xff0c;如下图所示&#xff0c;c a b&#xff0c;输入数字后&#xff0c;按 “” 就计算。 步骤 拖拽三个 Edit Field(Numeric) 过来&#xff0c;并且双击名字分别改为 a,b,c。注意修改名字后右边会有点变…

SpringBoot 之配置加密

Jasypt库的使用 Jasypt是一个Java简易加密库&#xff0c;用于加密配置文件中的敏感信息&#xff0c;如数据库密码。 Jasypt库与springboot集成&#xff0c;在实际开发中非常方便。 1、引入依赖 <dependency><groupId>com.github.ulisesbocchio</groupId>&…

【操作系统笔记五】内存布局内存映射

虚拟内存布局 虚拟地址空间大小&#xff1a; 32位虚拟地址空间 [0 ~ 2^32 - 1] 总共4GB64位虚拟地址空间 [0 ~ 2^64 - 1] 总共16 777 216TB 不管是运行在用户态还是内核态&#xff0c;都需要使用虚拟地址&#xff0c;这是因为计算机硬件要求的&#xff0c;CPU要经过地址转换得…

更新andriod studio版本,项目编译报could not find org.junit.jupiter:junit-jupiter

原本使用Android Studio 版本是4.1.1&#xff0c;现更新为 点击build -》 build bundle -》build apk&#xff0c;项目报 Could not determine the dependencies of task :app:compileDebugUnitTestJavaWithJavac. > Could not resolve all task dependencies for configur…

HTML那些重要的知识点

文章目录 ⭐️写在前面的话⭐️一、HTML1.1 锚点链接跳转到当前页面的指定位置跳转到其他页面的指定位置 1.2 自定义列表1.3 表格的跨行跨列1.4 视频和音频内容1.5 页面结构规范1.6 ifram内联框架1.7 表单1.7.1 form标签1.7.2 原生表单部件1.7.3 下拉框1.7.4 文本域1.7.5 文件域…

基于微信小程序的健康评估系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言运行环境说明用户微信端的主要功能有&#xff1a;医生微信端的主要功能有&#xff1a;管理员的主要功能有&#xff1a;具体实现截图详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考论文参考源码获取…

【每日一题】658. 找到 K 个最接近的元素

658. 找到 K 个最接近的元素 - 力扣&#xff08;LeetCode&#xff09; 给定一个 排序好 的数组 arr &#xff0c;两个整数 k 和 x &#xff0c;从数组中找到最靠近 x&#xff08;两数之差最小&#xff09;的 k 个数。返回的结果必须要是按升序排好的。 整数 a 比整数 b 更接近 …

【PDF】pdf 学习之路

PDF 文件格式解析 https://www.cnblogs.com/theyangfan/p/17074647.html 权威的文档&#xff1a; 推荐第一个连接&#xff1a; PDF Explained &#xff08;译作《PDF 解析》&#xff09; | PDF-Explained《PDF 解析》https://zxyle.github.io/PDF-Explained/ https://zxyle…

怎样的外发文件管理办法 能够避免数据外发泄露?

在日常办公中&#xff0c;重要文件保密管理可谓“老生常谈”。但我们往往容易忽视&#xff0c;文件保密管理并非个体所能独立完成&#xff0c;在整个文件运转过程中&#xff0c;存在多名经手人&#xff0c;一人发生疏忽&#xff0c;则整个安全屏障都会被打破。 因此&#xff0c…

Jetpack Compose中的Navigation从入门到精通完全指南

Jetpack Compose中的Navigation从入门到精通完全指南 什么是Android导航 导航帮助您理解应用程序在不同组件间的移动方式。 Android JetPack Navigation可以帮助您以简单的方式实现高级导航。 导航组件由三个主要部分组成&#xff1a; 导航图(Navigation Graph)&#xff1…

前端关于对象中套用对象传参的小问题

在js的对象是引用类型的&#xff0c;他如果里面还套用对象的话那么通过axios传参给后端就会出现一个问题&#xff0c;就是【object&#xff0c;object】这种包装形式 那么如何来解决这个问题呢&#xff1f; 其实这就是要对数据传输中json格式要有一定的了解才可以解决这个问题…