MVC 写法 → MVVM

MVC 写法 → MVVM

老写法(Java --- Activity 承担一切)

java 复制代码
public class MainActivity extends AppCompatActivity {

    private TextView tvName;
    private ProgressBar progressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tvName = findViewById(R.id.tv_name);
        progressBar = findViewById(R.id.progress_bar);

        loadData();
    }

    private void loadData() {
        progressBar.setVisibility(View.VISIBLE);
        api.loadUser(new Callback<User>() {
            @Override
            public void onSuccess(User user) {
                progressBar.setVisibility(View.GONE);
                tvName.setText(user.getName());
            }

            @Override
            public void onError(String msg) {
                progressBar.setVisibility(View.GONE);
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }
}

问题在哪里

Activity 同时负责了 UI 绘制、数据请求、状态切换和业务逻辑,一个类三四百行是常态。测试完全没法做------所有逻辑都耦合在 Activity 里。屏幕旋转后数据丢失,需要手动处理 onSaveInstanceState

新写法(MVVM + ViewModel + LiveData)

kotlin 复制代码
// ViewModel
class MainViewModel(private val api: ApiService) : ViewModel() {

    private val _user = MutableLiveData<User>()
    val user: LiveData<User> = _user

    private val _isLoading = MutableLiveData(false)
    val isLoading: LiveData<Boolean> = _isLoading

    private val _error = MutableLiveData<String?>()
    val error: LiveData<String?> = _error

    fun loadUser() {
        viewModelScope.launch {
            _isLoading.value = true
            try {
                val result = withContext(Dispatchers.IO) { api.loadUser() }
                _user.value = result
            } catch (e: Exception) {
                _error.value = e.message
            } finally {
                _isLoading.value = false
            }
        }
    }
}

// Activity
class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.user.observe(this) { user -> tvName.text = user.name }
        viewModel.isLoading.observe(this) { isLoading ->
            progressBar.visibility = if (isLoading) View.VISIBLE else View.GONE
        }
        viewModel.error.observe(this) { msg -> msg?.let { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() } }

        viewModel.loadUser()
    }
}

一句话注意

最核心的变化:Activity 从"做事的人"变成"观察数据的人"。它不再调用接口、处理回调、切换状态,只负责监听 ViewModel 的数据变化并更新 UI。ViewModel 存活于 Activity 的生命周期之外,旋转屏幕不丢数据。

viewModels()activity-ktx 里的委托,自动创建和获取 ViewModel。ViewModel 内部用 viewModelScope 启动协程,这个 scope 在 ViewModel 被清除时自动取消。


Java Android 老项目迁移系列,持续更新中。

相关推荐
未秃头的程序猿3 小时前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
37手游移动客户端团队3 小时前
招聘-高级安卓开发工程师
android·客户端
用户298698530143 小时前
Word 文档文本查找与替换的 Java 实现方案
java·后端
阿哉4 小时前
Nacos 服务发现源码:藏在背后的两套事件机制,90%的人只讲了一半
java
用户41659673693554 小时前
WebView 请求异常排查操作手册
android·前端
咖啡八杯4 小时前
GoF设计模式——命令模式
java·设计模式·架构
AI人工智能_电脑小能手4 小时前
【大白话说Java面试题 第125题】【并发篇】第25题:说说 Java 线程的中断机制
java·后端·面试
Java内核笔记4 小时前
Spring Security 源码解析(六)无状态 JWT 实践:Session 共享与自定义过滤器
java·后端
荣码4 小时前
LangGraph多Agent协作:3个Agent干活比1个强,但我踩了4个坑
java·python
Kapaseker5 小时前
学不动了,入门 Compose Styles API
android·kotlin