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 老项目迁移系列,持续更新中。