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

【大前端】【Android】把 Activity 重构成 MVVM 的对比示例

同一个功能:加载用户并显示名字

功能不变:

点按钮 → 请求用户 → 显示用户名 → 失败提示


一、❌ 传统 Activity 写法(所有东西都在 Activity)

Activity(UI类)

public class UserActivity extends AppCompatActivity { TextView tvName; Button btnLoad; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user); tvName = findViewById(R.id.tvName); btnLoad = findViewById(R.id.btnLoad); btnLoad.setOnClickListener(v -> { // ① UI 事件 loadUser(); }); } private void loadUser() { // ② 业务逻辑 showLoading(); Api.getUser(new Callback<User>() { @Override public void onSuccess(User user) { // ③ 数据处理 tvName.setText(user.getName()); // 改 UI hideLoading(); } @Override public void onError(String msg) { // ④ 错误处理 Toast.makeText(UserActivity.this, msg, Toast.LENGTH_SHORT).show(); hideLoading(); } }); } }

❗问题在哪?

问题原因
Activity 很胖所有职责都在
不可测试依赖 Android
UI & 逻辑耦合直接操作 View
状态不可控loading / error 到处写

二、✅ 重构目标(先不看代码)

我们要做到:

Activity:我只管展示 ViewModel:我管逻辑和状态

Activity不再知道

  • 请求怎么发

  • 什么时候成功 / 失败

  • 状态怎么切换


三、✅ MVVM 写法(拆开)


1️⃣ ViewModel:专门“管状态”

public class UserViewModel extends ViewModel { // 用户名状态 private MutableLiveData<String> userName = new MutableLiveData<>(); // loading 状态 private MutableLiveData<Boolean> loading = new MutableLiveData<>(); // 错误信息 private MutableLiveData<String> errorMsg = new MutableLiveData<>(); public LiveData<String> getUserName() { return userName; } public LiveData<Boolean> getLoading() { return loading; } public LiveData<String> getErrorMsg() { return errorMsg; } public void loadUser() { loading.setValue(true); Api.getUser(new Callback<User>() { @Override public void onSuccess(User user) { userName.setValue(user.getName()); // 只改数据 loading.setValue(false); } @Override public void onError(String msg) { errorMsg.setValue(msg); // 只抛状态 loading.setValue(false); } }); } }

📌注意一个关键点

ViewModel从头到尾没有一句 UI 代码


2️⃣ Activity:变成“数据监听器”

public class UserActivity extends AppCompatActivity { private UserViewModel viewModel; private TextView tvName; private ProgressBar progressBar; private Button btnLoad; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_user); tvName = findViewById(R.id.tvName); progressBar = findViewById(R.id.progressBar); btnLoad = findViewById(R.id.btnLoad); viewModel = new ViewModelProvider(this).get(UserViewModel.class); // ① 监听数据 viewModel.getUserName().observe(this, name -> { tvName.setText(name); }); viewModel.getLoading().observe(this, show -> { progressBar.setVisibility(show ? View.VISIBLE : View.GONE); }); viewModel.getErrorMsg().observe(this, msg -> { if (msg != null) { Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); } }); // ② 把点击事件“交出去” btnLoad.setOnClickListener(v -> { viewModel.loadUser(); }); } }

四、最重要的一行对比(🔥核心)

以前

tvName.setText(user.getName());

现在

userName.setValue(user.getName());

👉UI 更新从“命令式”变成“数据驱动”


五、用一句话理解“重构发生了什么”

Activity 不再“做事”
ViewModel 不再“碰 UI”
它们通过“状态”交流


六、责任变化对照表(一定要看)

职责以前现在
点击处理ActivityActivity(转交)
网络请求ActivityViewModel
成功失败判断ActivityViewModel
UI 更新ActivityActivity
状态来源ActivityViewModel

七、已经“半只脚进 MVVM 了”的标志

如果现在能理解这句话:

Activity 不知道“什么时候该改 UI”,
它只知道“数据变了我就展示”

那已经抓住MVVM 的核心原理了。

http://www.cnnetsun.cn/news/52739.html

相关文章:

  • what?动态规划?
  • CommonJS 的缓存机制:为什么二次 require 得到的对象是同一个?
  • 跨标签页通信的五种方案:LocalStorage、BroadcastChannel 与 SharedWorker
  • JavaScript 与 CSS 变量交互:利用 setProperty 动态修改 CSS 变量实现主题切换
  • 2、UNIX基础入门教程
  • 6、互联网通信全解析:从邮件到多媒体的多元世界
  • vue基于Spring Boot框架 农产品销售供应商管理系统_m11i2507_
  • 10、UNIX系统管理:技术与实践指南
  • vue基于SpringBoot的健身房管理系统设计与实现_45vy0km9_
  • 父子进程关系与终止机制详解
  • Qt面试题合集(一)
  • Claude vs ChatGPT vs Gemini:全方位对比与选用指南
  • 大模型量化技术原理-ZeroQuant系列(一)
  • RISCV的异常和中断
  • vue基于Spring Boot框架的水果商城设计与实现_6628xfyb_
  • 【入门级-数据结构-3、特殊树:完全二叉树的定义与基本性质】
  • python用openpyxl操作excel-读取或创建excel文件
  • 刷题日记day5(二分+前缀和)
  • 005-AES:采招网
  • 基于python+django的在线考试系统(源码+lw+部署文档+讲解等)
  • C语言一维与二维数组名详解:从本质理解到高手应用
  • 当水印遇见AI:一场像素级的美学修复之旅
  • 软件测试是保障软件质量的关键环节,尤其在当前无法完全依赖形式化方法证明软件正确性的背景下,测试成为发现缺陷最主要、最有效的手段
  • 如何用AI快速生成Flink面试题答案?
  • 10分钟搞定:DeepSeek本地开发环境快速搭建方案
  • 豆包AI手机智能操控的硬核原理
  • CVE-2023-48795漏洞深度解析:原理与影响
  • 深入解析strspn:字符串扫描的精确尺子
  • 纺织AI设计系统:用技术重构创意与效率
  • 用AI辅助开发:weditor的自动化测试新体验