LiveData – 数据监听神器

LiveData我认为是Jetpack构架组件里最有用一个。

以前做项目的时候,不同页面里会经常显示一些通用信息,比如当前登录用户的用户名和头像等。这些信息都保存在数据层,你的UI如果想及时响应数据的变化,那么必须想办法去监听数据的变化。假设你的N个页面都有显示头像,那么用户进入你的App的设置页面,更改了头像,然后显示了头像的这些页面是不是得及时改变?

我以前是这么做的。使用EventBus,在各个需要显示头像的Activity里注册事件,用户改完了头像,发送一个事件,然后各个页面自己去更新。

LiveData提供了一个简洁优雅的方式来完成这种通用需求。我们可以给LiveData注册观察者,一旦数据变化,就可以响应。配合LifeCycle使用,可以获取当前Activity的LifeCycle,当LifeCycle到达DESTROYED状态的时候,把观察者给删除。也即是说,你在Activity的onCreate开始监听数据之后,就不用操心再在onDestroy去写代码了,取消监听是自动的,你省事儿了。

下面看一下使用方法:

MyData的成员变量userName是个LiveData,是从Repository中获取的,Repository是整个App的数据中心,像用户名这种全局数据都是保存在这里的。在Activity中,获取到userName,进行监听。LiveData.observe方法有两个参数,一个是LifeCycleOwner,用来获取LifeCycle的;另一个参数就是观察者。

好了,这样就能监听用户名变化了,UI也可以及时更新了。你可能有疑惑,observe方法只是用来监听变化,那么没变化的时候,我的userNameTextView是不是没办法显示用户名了?需不需要先把LiveData的值获取出来,给userNameTextView用,然后再进行observe的操作?

其实是不需要的。Observer的onChanged方法并不是每次数据变化都会执行的。之前我们学习LifeCycle的时候,了解过生命周期的状态,onChanged只会在STARTED和RESUMED的时候执行,也就是onStart()执行过之后,onStop()执行之前。更简单的说,LifeCycle状态是RESUMED和STARTED的时候,Observer是active的,LifeCycle是其他状态时,Observer是inactive的,只有active的时候,onChanged才会被执行。另外从inactive切换到active的时候,onChanged也会被执行(这种除外:数据和上次active时候一样)。所以在上面的代码中,只需要调用observe方法就行,在onStart()执行的时候,onChanged会自动被调用,如果LiveData中保存有值,就会更新。所以没必要在onCreate的时候就把LiveData的值取出来进行操作。

那LiveData中没数据怎么办?是不是得去获取呀。在我们的例程中,userName是全局数据,可以在应用启动的时候就发请求向服务器获取,或者从数据库读,或者从SharedPreferences中读。这样不论是在Activity启动前获取到数据,还是在Activity启动之后获取到数据,UI都能正常响应。除了全局的数据,还有一些页面相关的数据,比如一个Activity用来显示商品的列表。这个列表数据肯定是保存在ViewModel中的,因为Activity启动的时候会创建ViewModel,那么我们就在ViewModel的构造方法中去向服务器请求列表数据,Activity只负责监听就行。

同时,你可能会感觉例程中的MyData类有点多余,明明直接在Activity中使用Repository就行,干嘛还要放在ViewModel中多此一举?这主要是为了分层和解耦。Activity不需要关心数据从哪里来,只需要从ViewModel中取就行了。而且ViewModel还可能有其他的页面相关的数据,比如上面提到的商品列表。

Android官方教程中列举了LiveData的诸多优点,再此我就不一一列举了。不过它并不是完美的,在处理异常和错误的时候,稍微有点麻烦,我们以后再讲。

发表评论

电子邮件地址不会被公开。