Android开发 -- Jetpack 之 ViewModel 是什么【使用、快速入门、通俗解释】

全文阅读预计 10 分钟

这可能是你看过的最清晰明了的讲解

主题 👇

写在前面:由于 ViewModelLiveData 关联性强,在学习 ViewModel 的时候要结合 LiveData 同时学习

想要快速学习 LiveData ?请进入此链接学习我对于 LiveData 的快速及通俗讲解。 全文阅读预计 15 分钟。

官方定义ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据ViewModel 类让数据可在发生屏幕旋转等配置更改继续存在

问题来源(1):例如你的 APP 某个 Activity 中包含一个 列表,因为配置更改而重新创建 Activity(例如众所周知的屏幕旋转发生后需手动保存数据在旋转后进行恢复),新 Activity 必须重新提取列表数据,对于简单数据,Activity 可以使用 onSaveInstanceState() 方法从 onCreate() 中的捆绑包恢复数据,但这种方法仅适合可以序列化再反序列化但少量数据,不适合数量可能较大但数据,如用户列表或位图

问题来源(2):我们通常需要调用网络接口数据,网络数据需要一段时间才能返回结果,而我们需要管理这些调用,并确保系统销毁后清理这些调用来避免内存泄漏,项目内容的日益增多会使开发者花费大量时间进行维护,并且在因为配置更改重新创建对象的情况下(例如上面说的屏幕旋转的例子),会造成资源浪费,因为对象可能需要重新发出已经发出过的调用

所以,从界面控制器(Activity、Fragment 等)分离出试图数据所有权的做法更易行、高效且势在必行

使用 👇

引入 ViewModel

// build.gradle
dependencies {
    // ViewModel and LiveData
    def lifecycle_version = "2.1.0"
    implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
    // 或
    // implementation "androidx.lifecycle:lifecycle-extensions:2.1.0"
    // 前者创建一个变量主要是便于管理,假如说你还引入了 lifecycle 的其它东西那么他们都同时使用这个变量的版本号就好,以后升级版本的时候只需要改一个地方
}

需求实践

我们做一个模拟服务器获取一个列表数据并展示到 RecyclerView 上的例子

第一步:

// 创建一个 ViewModel 类
public class FourViewModel extends ViewModel {
    private MutableLiveData<List<User>> users;

    public LiveData<List<User>> getUserList() {
        if (users == null) {
            users = new MutableLiveData<>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // Handler 只为了模拟,你可以在这里通过你的网络框架 OkHttp、Retrofit 等进行网络操作
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                List<User> list = new ArrayList<>();
                list.add(new User());
                // ... 添加多个测试数据
                list.add(new User());
                users.setValue(list);
            }
        }, 2000);
    }
}

第二步:

// 将 Activity 继承自 AppCompatActivity
public class FourActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        FourViewModel model = ViewModelProviders.of(this).get(FourViewModel.class);
        model.getUserList().observe(this, new Observer<List<User>>() {
            @Override
            public void onChanged(List<User> users) {
                // recyclerView.setLayoutManager...
                // recyclerView.setAdapter...
            }
        });
    }
}

ViewModel 是什么:它相当于界面控制器的辅助程序类,负责为界面准备数据,在配置更改期间会自动保留 ViewModel 对象,便于他们存储的数据立即可供下一个 Activity、Fragment 实例使用。例如上面的例子:如果您需要在应用中显示用户列表,请确保将获取和保留该用户列表的责任分配给 ViewModel 而不是 Activity、Fragment

!!!ViewModel 绝不能引用视图、Lifecycle 或可能存储对 Activity 上下文对引用对任何类!!!

ViewModel 对象存在的时间比视图或 LifecycleOwners 的特定实例存在的时间更长。还意味着,你可以更轻松地编写涵盖 ViewModel 的测试,因为它不了解视图和 Lifecycle 对象。ViewModel 对象可以包含 LifecycleObservers,如 LiveData 对象。但是,ViewModel 对象绝不能观察对生命周期感知型可观察对象(如 LiveData 对象)的更改。 如果 ViewModel 需要 Application 上下文(例如,为了查找系统服务),它可以扩展 AndroidViewModel 类并设置用于接收 Application 的构造函数,因为 Application 类会扩展 Context

// 也就是说如果你想用 context 可以继承自 AndroidViewModel
// 就可以得到 Application 对象了再通过 Application 获取 context
public class FourViewModel extends AndroidViewModel {
    public FourViewModel(@NonNull Application application) {
        super(application);
        // do something...
    }
}

文末 👇

OK,到这里就是 ViewModel 入门讲解了,你会发现代码变多了,但是仔细想想,当我们接手别人项目的时候最难懂的是什么:是混乱的逻辑。上面的代码量虽然多了一点,但使代码的逻辑变得清晰了,何尝不是一件好事呢~

在此,你已经在极少对时间内对于 ViewModel 有了新的认识,现在我推荐你学习如何通过 MVVM框架 来编写以后的代码,它的优势是使你的代码逻辑更加清晰以减少开发时间。

想要快速学习 MVVM 框架?请进入此链接学习我对于 MVVM 的快速及通俗讲解。 全文阅读预计 10 分钟。

码字不易,还请动动小手左侧栏中点赞 👍,3Q

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值