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 Activity / Fragment 观察 LiveData,更新 UI 用户操作 ViewModel 持有 LiveData 处理业务逻辑 数据请求 Model Repository 数据源 数据通过 LiveData 回调 MVVM 数据流:View → ViewModel → Model → (LiveData) → View 注意:ViewModel 不持有 View 的引用,避免内存泄漏

看到没?数据是单向流动的。用户点击按钮,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 的大门已经推开,后面咱们会深入每个组件的细节。记住,动手写代码才是最好的学习方式。


公众号:蓝海资料掘金营,微信 deep3321