当前位置: 首页 > 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.jsqmd.com/news/88847/

相关文章:

  • Java后端第一次学习计划
  • 实习面试题-PHP 面试题
  • 【大前端】【Android】一文详解为什么ViewModel的observe能监听到数据的变化
  • 深入理解 IndexedDB:在浏览器中存储 PB 级数据的事务性 API 实战
  • Fastapi的单进程响应问题 和 解决方法
  • 游戏运行库合集:一站式解决游戏依赖问题的完整组件包
  • 数字员工是什么?熊猫智汇如何助力AI销售工具效率提升?
  • 基于PLCS7 - 200的饮料自动机设计分享
  • 实习面试题-Shell 面试题
  • JavaScript 代码混淆与反混淆:利用 AST 变形提升代码安全性
  • 5MW 风电机组 LQR 功率调节:带状态观测器的探索之旅
  • CF234G Practice - crazy-
  • 实习面试题-MapReduce 面试题
  • 11、UNIX安装基础全解析
  • 基于Simulink的双向DCDC变换器系统仿真
  • 2025年数字化转型:AI技能+CAIE认证夯实进阶根基
  • 软件工程期末考试-数据流图、状态图、用例图、类图等怎么画?
  • CF1475C Ball in Berland - crazy-
  • 大数据领域体系认知
  • 储能系统双向 DCDC 变换器双闭环控制:解锁蓄电池充放电仿真的奥秘
  • CF1506C Epic Transformation - crazy-
  • 服务端渲染(SSR)中的 JS 激活(Hydration):前后端状态同步的底层挑战
  • 2025年男孩取名机构推荐:权威榜单TOP5机构深度解析 - 十大品牌推荐
  • 1、深入了解 UNIX 操作系统:特性、历史与哲学
  • CF1536C Diluc and Kaeya - crazy-
  • JavaScript 源代码的 AST 转换:Babel 插件是如何改变你编写的代码的?
  • 2、UNIX基础入门教程
  • 2025年男孩取名机构推荐:2025年专业取名机构权威榜单TOP5深度解析 - 十大品牌推荐
  • 2025年互联网行业:AI技能+CAIE认证打造核心竞争力
  • CF1538F Interesting Function - crazy-