1、Jetpack初探:Jetpack简介、MVVM架构思想、ViewModel与LiveData快速上手
各位同学,咱们正式开始啃 Android Jetpack 这块硬骨头。说实话,我刚开始接触 Jetpack 的时候,心里也犯嘀咕——这玩意儿不就是 Google 又搞出来的一套新轮子吗?但真正用上之后,我只能说:真香。
这一章,咱们不整那些虚的。直接上手,先搞清楚 Jetpack 到底是什么,再说说它背后的 MVVM 思想,最后用 ViewModel 和 LiveData 写个能跑的小例子。嗯,跟着我来,保证不迷路。
1.1 Jetpack 是什么?
Jetpack 是 Google 在 2018 年推出的一套 Android 组件库合集。说白了,它就是帮你解决 Android 开发中那些「重复造轮子」的问题。比如生命周期管理、数据持久化、UI 绑定、后台任务……这些每个 App 都会遇到的需求,Jetpack 都给你封装好了。
我个人习惯把 Jetpack 分成四大类:
- 基础组件:AppCompat、Android KTX、Multidex 等,属于「地基」。
- 架构组件:ViewModel、LiveData、Room、WorkManager 等,这是咱们课程的重点。
- 行为组件:CameraX、Permissions、DownloadManager 等,处理系统交互。
- UI 组件:Compose、Fragment、ConstraintLayout 等,负责界面展示。
你想想看,以前写一个列表页,要自己处理旋转屏幕时的数据保存、要手动管理网络请求的生命周期、还要写一堆 findViewById……现在 Jetpack 把这些脏活累活全包了。我当年做第一个项目时,光是一个屏幕旋转就折腾了两天,现在想想真是血泪史。
核心观点:Jetpack 不是银弹,但它能让你少写 60% 的样板代码。尤其是架构组件,直接改变了我们写 Android 的方式。
1.2 MVVM 架构思想
聊 Jetpack 之前,必须先搞懂 MVVM。为什么?因为 Jetpack 的架构组件就是为 MVVM 量身定做的。
MVVM 全称是 Model-View-ViewModel,它把界面、数据和业务逻辑彻底拆开。我画了张图,你看一眼就明白了:
看到没?数据是单向流动的。用户点击按钮,View 通知 ViewModel,ViewModel 去 Model 拿数据,数据通过 LiveData 推回 View。这样每个模块各司其职,测试起来也方便。
我在项目中遇到过最典型的反面教材:有人把网络请求直接写在 Activity 里,结果屏幕一旋转,请求断了,数据丢了,用户还得重新加载。用 MVVM + ViewModel 之后,这种问题再也没出现过。
小技巧:MVVM 的核心是「ViewModel 不知道 View 的存在」。它只暴露 LiveData,View 自己去订阅。这样 ViewModel 就能跨 Activity 重建存活。
1.3 ViewModel 快速上手
ViewModel 是 MVVM 里的「大脑」。它的最大特点就是:不怕屏幕旋转。Activity 销毁重建时,ViewModel 还活着。数据不用重新加载。
来看代码,咱们写一个最简单的计数器:
// 1. 创建 ViewModel
public class CounterViewModel extends ViewModel {
private int count = 0;
public int getCount() {
return count;
}
public void increment() {
count++;
}
}
// 2. 在 Activity 中使用
public class MainActivity extends AppCompatActivity {
private CounterViewModel viewModel;
private TextView tvCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取 ViewModel
viewModel = new ViewModelProvider(this).get(CounterViewModel.class);
tvCount = findViewById(R.id.tv_count);
tvCount.setText(String.valueOf(viewModel.getCount()));
findViewById(R.id.btn_increment).setOnClickListener(v -> {
viewModel.increment();
tvCount.setText(String.valueOf(viewModel.getCount()));
});
}
}
嗯,这里要注意:ViewModelProvider 是 Jetpack 提供的工具类。它会帮你管理 ViewModel 的生命周期。Activity 旋转后,你拿到的还是同一个 ViewModel 实例。
警告:千万不要在 ViewModel 里持有 Activity 或 View 的引用!否则会导致内存泄漏。我曾经见过有人把 Context 传进 ViewModel,结果 Activity 销毁了 ViewModel 还拽着不放,内存直接炸了。
1.4 LiveData 快速上手
LiveData 是 ViewModel 和 View 之间的「信使」。它是一个可观察的数据容器,而且能感知生命周期。什么意思?就是 Activity 在前台时它才更新 UI,后台时自动暂停,避免空指针。
咱们把上面的计数器改成 LiveData 版本:
// 1. ViewModel 使用 LiveData
public class CounterViewModel extends ViewModel {
private MutableLiveData<Integer> countLiveData = new MutableLiveData<>(0);
public LiveData<Integer> getCount() {
return countLiveData;
}
public void increment() {
countLiveData.setValue(countLiveData.getValue() + 1);
}
}
// 2. Activity 观察 LiveData
public class MainActivity extends AppCompatActivity {
private CounterViewModel viewModel;
private TextView tvCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewModel = new ViewModelProvider(this).get(CounterViewModel.class);
tvCount = findViewById(R.id.tv_count);
// 观察 LiveData
viewModel.getCount().observe(this, count -> {
tvCount.setText(String.valueOf(count));
});
findViewById(R.id.btn_increment).setOnClickListener(v -> {
viewModel.increment();
});
}
}
看到区别了吗?Activity 不再主动去「拉」数据,而是「等」数据推送过来。LiveData 一旦变化,自动更新 UI。而且 observe() 的第一个参数传了 this(LifecycleOwner),LiveData 会自动管理订阅的生命周期。
我个人习惯把 LiveData 和 ViewModel 搭配使用,几乎成了标准配置。你想想看,以前写回调接口、写 Handler、写 EventBus……现在一个 LiveData 全搞定,代码干净多了。
最佳实践:ViewModel 内部用 MutableLiveData,对外暴露 LiveData(只读)。这样外部只能观察,不能修改,数据安全有保障。
1.5 避坑指南
最后,分享几个我踩过的坑:
- LiveData 数据倒灌:Activity 重建后,LiveData 可能会把旧数据再发一遍。解决方案是用
SingleLiveEvent或者EventWrapper包装一下。 - ViewModel 不要传 Context:如果非要使用 Application 级别的 Context,用
AndroidViewModel代替ViewModel。 - LiveData 的 setValue 和 postValue:主线程用
setValue,子线程用postValue。混用会导致数据丢失,我吃过这个亏。
好了,这一章的内容就到这里。Jetpack 的大门已经推开,后面咱们会深入每个组件的细节。记住,动手写代码才是最好的学习方式。