首先明白Jetpack 是一套库、工具和指南,可帮助开发者更轻松地编写优质应用,架构包含了数据绑定(Data Binding)、Lifecycles(关于 activity 以及 fragment 的生命周期)、 LiveData(用于更新界面的数据,跟大家之前理解的 model 不一样,它可以感应生命周期)、Navigation(关于 APP 内的导航跳转)、Paging(可以理解为分页加载)、Room(原来有很多第三方的数据库 ormlite 之类的,现在 Google 出手了,这是对 sqlite 数据库的进一步封装)、 ViewModel(前面说了 LiveData,而 ViewModel 就是用来管理 LiveData 的,用于连接 view 视图层和 LiveData 数据层,更重要的是它可以感应声明周期)、WorkManager(用于管理后台任务)。
我们时常需要和Activity、Fragment 的生命周期打交道,它们本身也提供了各自一套生命周期的方法,我们只需要在相应的方法里面做正确的事情即可,但是我们有没有想过,这样对于 Activity 和 Fragment 来说,功能过于复杂了,那么如何将这一块业务逻辑从我们的视图之中迁移到业务层呢?
解决方案:主要为了从Activity中分离处理生命周期的功能,使用实现了 LifecycleOwner 的 Fragment、Activity,比如 V4包下的 Fragment、FragmentActivity、AppCompatActivity 之类的,lifecycleOwner 与传统的 Activity、fragment 不同之处是lifecycleOwner是一个接口,而不是一个实现类,这意味着任何类都可以实现这个接口,从而监听 Activity、Fragment 的生命周期变化. lifecycle官方文档
当我们开发的APP 需要适配键盘状态、屏幕旋转、语言变化等 configure 改变会导致 Activity销毁重建,这个时候 Activity 持有的数据就会全部丢失,在Activity 重建之后我们又要去重新获取数据,这期间可能会对用户体验造成不良影响,传统的解决办法是在 onSaveInstanceState方法中保存,在 onCreate中恢复,这样不仅会让 UI 层代码臃肿,而且存储的数据还必须是可序列化的。那么有没有办法将这部分逻辑从 UI 层中移除呢?
解决方案:当 Activity、Fragment 被重新创建的时候,通过 ViewModelProvides 可以重新获得与之关联的 ViewModel,从而确保数据不会丢失。ViewModel 被存储在 ViewModelStore 类中,当与之关联的 Activity、Fragment 被 finish 之后最终会调用 ViewModel 的 onCleared 方法,到这里之后 ViewModel 才会被释放掉. ViewModel官方文档
当 Activity 处于前台的时候被销毁了,那么得到的 ViewModel 是之前实例过的 ,如果 Activity 处于后台时被销毁了,那么得到的 ViewModel 不是同一个
当我们的 Activity、Fragment 不可见的时候,我们是不需要也不应该刷新 UI 的。比如开启一个倒计时任务,从10倒数到0,我们期望当我们的 Actvity、Fragment 不可见的 时候我们的计时器依然是有效的,但是不会去刷新 UI 的显示,在倒数过程中如果我们让我们的 Activity、Fragment 变得可见的时候,视图应该正确显示现在倒数到的最新数字,通过在设置视图显示文本的时候手动判断当前 Activity、Fragment 的生命周期可以达到我们的期望,但是手动是不可靠的,有没有自动的方式实现我们的期望呢?
解决方案:LiveData 提供一个Observer接口给客户端,客户端实现这个接口,并将引用传递给它,当我们调用 LiveData 的 setValue 或 postValue 的时候,LiveData 就会去回调这个接口的方法,其实也就是LiveData 自己实现了观察者模式。不过 LiveData 搞定了一个让我们长期以来头疼的事情,那就是当 Activity、Fragment 不可见的时候 UI 不要更新的问题,其内部其实也是监听了 LifecycleOwner 的可见和不可见的方法,当 Activity、Fragment 不可见的时候就不回调 Observer 的方法,当 Activity、Fragment 变成可见的时候,就对比最新的值和最后发出去的值是否是同一个,不同的话就发送最新的值,确保 Activity、Fragment 可见的时候用户看到的一定是最新的数据。
LiveData官方文档
LiveData主要有以下几个有点:
一,保证数据与界面的实时更新
LiveData采用了观察者模式设计,其中LiveData是被观察者,当数据发生变化时会通知观察者进行数据更新。通过这点,可以确保数据和界面的实时性。
二,有效避免内存泄漏
这是因为LiveData能够感知到组件的生命周期,当组件状态处于DESTROYED状态时,观察者对象会被remove。
三,Activity/Fragment销毁掉时不会引起崩溃
这是因为组件处于非激活状态时,在界面不会收到来自LiveData的数据变化通知。这样规避了很多因为页面销毁之后,修改UI导致的crash。
四,不需要手动处理生命周期
LiveData能够感知组件的生命周期,所以设置LiveData组件的生命周期状态。
五,始终能够保持最新数据
生命周期从非活跃状态切换到活跃状态的时候,能够实时的接收最新的数据。
六,能够应对配置更改
由于LiveData保存数据的时候,组件和数据是分离的,所以在配置更改(如横竖屏切换等)的时候,即便组件被重新创建,因为数据还保存在LiveData中,这样也能够做到实时的更新。
七,资源共享
单例模式扩展LiveData对象并包装成系统服务,以便在应用程序中进行共享,需要该资源的只需要观察LiveData即可
说明:一般来说我们会在 ViewModel 中创建 Livedata 对象,然后再 Activity/Fragment 的 onCreate 中注册 Livedata 监听,因为在 onStart 和 onResume 中进行监听可能会有冗余调用
注意: 我们知道Android中更新UI需要在主线程中操作,因此LiveData setValue的时候也需要在主线程中。如果想在子线程中改变LiveData的值,可以调用postValue(T) 方法来更新 LiveData 对象
总结:首先 LifecycleOwner 和 ViewModel 是一定要处处用到的虽然人家叫做 ViewModel,但是对于我们选择用 MVP 或者是 MVVM 并没有什么冲突,因为ViewModel 的概念和这两种架构没有冲突,所以剩下的就是 LiveData 了,LiveData 的使用场景适合在一个信号量在多处改变的时候使用,当一个信号量只在一个地方改变,那么用不用 LiveData 其实差不不大。所以我的定位是一个信号量在多处地方改变的时候.
网友评论