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

Android 架构模式之 MVC

目录

    • 架构设计的目的
    • 对 MVC 的理解
    • Android 中 MVC 的问题
    • 试吃个小李子
      • View
      • Model
      • Controller

大家好!

作为 Android 程序猿,MVC 应该是我们第一个接触的架构吧,从开始接触 Android 那一刻起,我们就开始接触它,可还记得我们写的第一个 App 代码的样子?

架构设计的目的

通过设计使程序模块化,模块内 高内聚、模块间 低耦合,提高开发效率,便于复用及后续维护。

对 MVC 的理解

MVC 架构图,箭头代表事件流向

上图是 MVC 的架构图,我们都知道,MVC架构中 M 代表 Model(模型)、V 代表 View(视图)、C 代表 Controller(控制器)。它们的职责分别是:

  1. View 负责接收用户的输入事件,然后将事件传递给 Controller;
  2. Controller 收到事件后,会进行业务处理,通知 Model 请求数据;
  3. Model 拿到数据后返回给 Controller 进行后续处理,或者通知 View 更新 UI。

Android 中 MVC 的问题

不幸的是,在 Android 中,通常由 Activity 充当 Controller,与此同时,由于 xml 的弱功能性,导致 Activity 还需要负责视图的显示,所以原本是负责初始化页面的 Activity,就变成了 View 和 Controller 的载体,导致这两部分内容耦合在 Activity 中。后果就是Activity 越来越臃肿、难以维护。这就违反了架构设计的初衷,所以就有了后来的MVP。

试吃个小李子

点击按钮,请求 wanandroid 网站的 banner 接口数据,请求成功后更新到UI上显示接口数据

代码结构

View

一个Button,点击请求接口数据
一个TextView,用于回显接口返回的数据

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center"android:orientation="vertical"tools:context=".MainActivity"><Buttonandroid:id="@+id/btn_get_banner_info"android:layout_width="wrap_content"android:layout_height="wrap_content"android:onClick="getBannerInfo"android:text="@string/get_banner_info" /><TextViewandroid:id="@+id/tv_banner_info"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout>

Model

请求接口

Repository.java

public final class Repository {private ApiService mService;private Repository() {createService();}public static Repository getInstance() {return SingletonHolder.sInstance;}private static final class SingletonHolder {private static final Repository sInstance = new Repository();}/*** 请求 banner 数据*/public void getBanners(ResponseCallback<List<Banner>> callback) {mService.getBanners().enqueue(new Callback<BaseResponse<List<Banner>>>() {@Overridepublic void onResponse(Call<BaseResponse<List<Banner>>> call, Response<BaseResponse<List<Banner>>> response) {BaseResponse<List<Banner>> body = response.body();if (response.isSuccessful() && body != null) {if (body.getErrorCode() == 0) {callback.onSuccess(body.getData());} else {callback.onFail(body.getErrorMsg());}} else {callback.onFail(response.message());}}@Overridepublic void onFailure(Call<BaseResponse<List<Banner>>> call, Throwable throwable) {callback.onFail(throwable.getMessage());}});}private void createService() {Retrofit retrofit = new Retrofit.Builder().baseUrl(HttpConstant.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();mService = retrofit.create(ApiService.class);}
}

Controller

获取数据
更新UI

MainActivity.java

public class MainActivity extends AppCompatActivity implements ResponseCallback<List<Banner>> {private TextView mBannerInfoTv;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mBannerInfoTv = (TextView) findViewById(R.id.tv_banner_info);}/*** 按钮点击事件* @param view*/public void getBannerInfo(View view) {getBanners();}/*** 获取 banner 数据*/private void getBanners() {Repository.getInstance().getBanners(this);}@Overridepublic void onSuccess(List<Banner> banners) {if (banners != null && banners.size() > 0) {showBannerInfo(banners);}}@Overridepublic void onFail(String msg) {Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT);}/*** 更新UI* @param banners*/private void showBannerInfo(List<Banner> banners) {StringBuilder sb = new StringBuilder("wanandroid 官网\nhttps://www.wanandroid.com\n\n");for(Banner item : banners) {sb.append(item.getTitle()).append('\n');}mBannerInfoTv.setText(sb.toString());}
}

附上源码链接

致谢:
感谢 wanandroid 提供的开放API

参考:
MVC、MVP、MVVM,我到底该怎么选?

写在最后:
很荣幸成为一名 Android 程序猿,虽然不是一名合格的猿。一路走来磕磕绊绊,借此感谢帮助过我的人,感谢指点、感恩遇见!

相关文章:

Android 架构模式之 MVC

目录 架构设计的目的对 MVC 的理解Android 中 MVC 的问题试吃个小李子ViewModelController 大家好&#xff01; 作为 Android 程序猿&#xff0c;MVC 应该是我们第一个接触的架构吧&#xff0c;从开始接触 Android 那一刻起&#xff0c;我们就开始接触它&#xff0c;可还记得我…...

节点使用简介:comfyui-photoshop

1、安装comfyui-photoshop 略过 一点要注意的是&#xff1a;在Photoshop上的安装增效工具&#xff0c;要通过Creative Cloud 桌面应用程序进行安装&#xff0c;才能成功在增效工具中显示&#xff0c;直接通过将文件解压到Plug-ins路径行不通&#xff08;至少对我来说行不通&am…...

使用Go语言将PDF文件转换为Base64编码

使用 Go 语言将 Base64 编码转换为 PDF 文件-CSDN博客本文介绍了如何使用 Go 语言将 Base64 编码转换为 PDF 文件&#xff0c;并保存到指定路径。https://blog.csdn.net/qq_45519030/article/details/141225772 在现代编程中&#xff0c;数据转换和编码是常见的需求。本文将介绍…...

XSS Game

关卡网址&#xff1a;XSS Game - Learning XSS Made Simple! | Created by PwnFunction 1.Ma Spaghet! 见源代码分析得&#xff0c;somebody接收参数&#xff0c;输入somebody111查看所在位置 使用input标签 <input onmouseoveralert(1337)> 2.Jefff jeff接收参数,在ev…...

???牛客周赛55:虫洞操纵者

题目描述 \,\,\,\,\,\,\,\,\,\,你需要在一个可以上下左右移动的 nnn\times nnn 棋盘上解开一个迷宫&#xff1a;棋盘四周都是墙&#xff1b;每个方格要么是可以通过的空方格 ′0′\sf 0′0′ &#xff0c;要么是不可通过的墙方格 ′1′\sf 1′1′ &#xff1b;你可以沿着空方格…...

Unity3D开发之OnCollisionXXX触发条件

A和B碰撞触发OnCollision函数条件如下&#xff1a; 1.A和B都要有collider。&#xff08;子物体有也可以&#xff09; 2.A和B至少有一个刚体&#xff08;Rigidbody&#xff09;组件&#xff0c;且刚体的isKinematic为false。如果为true不会触发。 3.挂载脚本的物体必须有刚体…...

spfa()算法(求最短路)

spfa算法是对bellman_ford算法的优化&#xff0c;大部分求最短路问题都可以用spaf算法来求。 注意&#xff1a; &#xff08;1&#xff09;如若图中有负权回路&#xff0c;不能用spfa算法&#xff0c;要用bellman_ford算法&#xff1b;若只有负权边&#xff0c;则可以用 spf…...

聊聊国产数据库的生态系统建设

生态系统是指在自然界中&#xff0c;生物与环境构成统一的整体&#xff0c;之间相互影响相互制约&#xff0c;并在一定时期内处于相对稳定的动态平衡状态。所谓数据库的生态系统&#xff0c;从用户的角度看&#xff0c;就是充分打通产品使用过程中上下游的关联&#xff0c;使其…...

JDK源码解析:LinkedList

1、背景 我们咨询一下腾讯混元大模型&#xff0c;什么是“LinkedList”。 以下是混元大模型的回答&#xff1a; LinkedList 是 Java 集合框架中的一种数据结构&#xff0c;它实现了 List 和 Deque 接口。LinkedList 是一个双向链表&#xff0c;这意味着每个元素都包含对前一个和…...

drawio的问题

drawio的问题 先给出drawio的链接https://app.diagrams.net/ 我在用overleaf写论文的过程中&#xff0c;发现了一个问题&#xff0c;就是使用drawio画好图之后&#xff0c;只能保存以下几个选项&#xff1a; 但是不管是什么类型&#xff0c;在overleaf上面图片都不显示。如果…...

零基础学习Redis(3) -- Redis常用命令

Redis是一个 客户端-服务器 结构的程序&#xff0c;Redis客户端和服务器可以在同一台主机上&#xff0c;也可以在不同主机上&#xff0c;客户端和服务器之间通过网络进行通信。服务器端负责存储和管理数据。客户端则可以通过命名对服务端的数据进行操作。 Redis客户端有多种&a…...

响应式Web设计:纯HTML和CSS的实现技巧-1

响应式Web设计&#xff08;Responsive Web Design, RWD&#xff09;是一种旨在确保网站在不同设备和屏幕尺寸下都能良好运行的网页设计策略。通过纯HTML和CSS实现响应式设计&#xff0c;主要依赖于媒体查询&#xff08;Media Queries&#xff09;、灵活的布局、可伸缩的图片和字…...

FrereRTOS事件组

文章目录 一、事件组概念与操作1、事件组的概念2、事件组的操作 二、事件组函数1、创建2、删除3、设置事件4、等待事件5、同步点 三、示例&#xff1a;广播四、示例&#xff1a;等待一个任意事件五、示例: 等待多个事件都发生 学校组织秋游&#xff0c;组长在等待&#xff1a; …...

【经典算法】BFS_最短路问题

目录 1. 最短路问题介绍2. 算法原理和代码实现(含题目链接)1926.迷宫中离入口最近的出口433.最小基因变化127.单词接龙675.为高尔夫比赛砍树 3. 算法总结 1. 最短路问题介绍 最短路径问题是图论中的一类十分重要的问题。本篇文章只介绍边权为1(或边权相同)的最简单的最短路径问…...

【题目/训练】:双指针

引言 我们已经在这篇博客【算法/学习】双指针-CSDN博客里面讲了双指针、二分等的相关知识。 现在我们来做一些训练吧 经典例题 1. 移动零 思路&#xff1a; 使用 0 当做这个中间点&#xff0c;把不等于 0(注意题目没说不能有负数)的放到中间点的左边&#xff0c;等于 0 的…...

LLVM - 编译器后端-指令选择

一&#xff1a;概述 任何后端的核心都是指令选择。LLVM 实现了几种方法&#xff1b;在本篇文章中&#xff0c;我们将通过选择有向无环图&#xff08;DAG&#xff09;和全局指令选择来实现指令选择。 在本篇文章中&#xff0c;我们将学习以下主题&#xff1a; • 定义调…...

ES+FileBeat+Kibana日志采集搭建体验

1.环境准备 需要linux操作系统&#xff0c;并安装了docker环境 此处使用虚拟机演示。&#xff08;虚拟机和docker看参考我之前写的文章&#xff09; VirtualBox安装Oracle Linux 7.9全流程-CSDN博客 VirtualBox上的Oracle Linux虚拟机安装Docker全流程-CSDN博客 简单演示搭建ES…...

Dockerfile常用指令详解

Dockerfile 是一个用于定义 Docker 镜像构建过程的脚本文件&#xff0c;其中包含了一系列指令&#xff0c;用于指定如何构建和配置镜像。以下是一些常用的 Dockerfile 指令及其示例用法&#xff1a; 1. FROM 指定基础镜像&#xff0c;Dockerfile 必须以该指令开始。 示例&am…...

【vue】浏览器兼容相关

Vue.js 是一个流行的前端 JavaScript 框架&#xff0c;它支持构建单页应用和复杂的用户界面。Vue.js 的核心库本身对浏览器的支持情况如下&#xff1a; Vue.js 2.x 最低支持版本&#xff1a;IE9 及以上版本。特性支持&#xff1a;ES5。兼容性&#xff1a;Vue 2.x 在发布时就考…...

【区块链+金融服务】基于区块链的区域股权金融综合服务平台 | FISCO BCOS应用案例

区域性股权市场是我国资本市场的重要组成部分&#xff0c;是多层次资本市场体系的基石。区块链技术与区域性股权市场 分散特征天然匹配&#xff0c;从新型金融基础设施层面为场外参与各方提供公共的可信服务&#xff0c;以技术手段完善市场基础条 件&#xff0c;弥补区域性短板…...

Blaze分块计算优化技巧:5个方法提升大数据处理性能

Blaze分块计算优化技巧&#xff1a;5个方法提升大数据处理性能 【免费下载链接】blaze NumPy and Pandas interface to Big Data 项目地址: https://gitcode.com/gh_mirrors/bl/blaze Blaze是一个强大的大数据处理工具&#xff0c;它通过分块计算技术为NumPy和Pandas提供…...

AI 大模型绘图日常使用教程|零门槛上手,快速出图不踩坑

摘要日常办公、学习中&#xff0c;我们经常需要各类图片 ——PPT 配图、工作流程图、活动海报、课件插画等&#xff0c;手动绘制耗时费力&#xff0c;专业设计软件又难上手。本文整合目前最实用、免费 / 低成本的 AI 绘图大模型&#xff0c;从工具选择、基础操作到进阶技巧&…...

无人机视角热成像行人车辆检测数据集VOC+YOLO格式2755张2类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数)&#xff1a;2755标注数量(xml文件个数)&#xff1a;2755标注数量(txt文件个数)&#xff1a;2755标注类别…...

告别样本不平衡噩梦:Focal Loss 让你的模型学会“划重点”

我说的不是 Python 那个 HTTPX 客户端&#xff0c;而是 ProjectDiscovery 出的 httpx。官方对它的定义很直接&#xff1a; 一个高性能、面向多探针的 HTTP 工具包支持高并发下对 URL、主机、CIDR 等 目标做 HTTP 层探测&#xff0c;并尽量保证结果稳定性。 它本质上不是漏洞扫描…...

10xGenomics单细胞测序选3‘还是5‘?一文讲清免疫组库与基因表达分析的黄金选择

10xGenomics单细胞测序&#xff1a;3与5端策略在免疫组库与基因表达分析中的科学抉择 当实验室的离心机停止运转&#xff0c;科研人员往往面临一个关键抉择&#xff1a;该选择3还是5端单细胞测序&#xff1f;这个看似技术性的选择&#xff0c;实则直接影响着后续免疫组库分析的…...

中国蚁剑启动报错全解析:从加载失败到空白界面的终极修复指南

1. 中国蚁剑启动报错的三大常见场景 第一次打开中国蚁剑就遇到报错&#xff0c;那种感觉就像刚拿到新玩具却发现电池没电。根据我这些年处理过的案例&#xff0c;启动问题主要集中在三个方向&#xff1a;界面加载失败、解压权限错误和空白界面。这些问题看似复杂&#xff0c;其…...

自己搭建永磁同步电机参数变动模块:为预测控制助力

永磁同步电机参数不确定/参数变化/参数失配/参数摄动模块 其中直交轴电感,电阻,磁链&#xff0c;转动惯量&#xff0c;粘滞摩擦系数可设置为自己所需的时变工况 适合做预测控制的同志们 由于MATLAB封装模块不可改动&#xff0c;于是自己搭建了这个模块,默认版本为2021b最近在研…...

如何在广告泛滥的时代找到纯粹的音乐净土?铜钟音乐的极简听歌方案

如何在广告泛滥的时代找到纯粹的音乐净土&#xff1f;铜钟音乐的极简听歌方案 【免费下载链接】tonzhon-music 铜钟 (Tonzhon.com): 免费听歌; 没有直播, 社交, 广告, 干扰; 简洁纯粹, 资源丰富, 体验独特&#xff01;(密码重置功能已回归) 项目地址: https://gitcode.com/Gi…...

Linux 系统调用实现原理

Linux 系统调用实现原理 系统调用的重要性 作为科技创业者&#xff0c;我深刻理解系统调用在操作系统中的核心地位。系统调用是用户空间与内核空间交互的桥梁&#xff0c;是应用程序访问操作系统服务的唯一途径。深入理解系统调用的实现原理&#xff0c;对于系统性能优化和安全…...

AI系统架构评审中的可扩展性设计:3个关键策略

AI系统架构评审中的可扩展性设计:3个关键策略 摘要 在AI技术飞速发展的今天,系统可扩展性已成为决定AI项目成败的关键因素之一。本文深入探讨了AI系统架构评审中可扩展性设计的三个核心策略:分布式计算与存储架构、模型解耦与服务化设计以及自适应资源调度与弹性扩展。通过…...