首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android程序员该如何去手写事件通信方案LiveDataBus

Android程序员该如何去手写事件通信方案LiveDataBus

作者头像
Android技术干货分享
发布2019-03-26 18:02:21
1.3K0
发布2019-03-26 18:02:21
举报
文章被收录于专栏:Android技术分享Android技术分享

Android LiveData定义

简单地说,LiveData是一个数据持有类。它具有以下特点:

  1. 数据可以被观察者订阅;
  2. 能够感知组件(Fragment、Activity、Service)的生命周期;
  3. 只有在组件出于激活状态(STARTED、RESUMED)才会通知观察者有数据更新;

一、​为什么需要LiveData

从LiveData具有的特点,我们就能联想到它能够解决我们遇到的什么问题。LiveData具有以下优点:

1.能够保证数据和UI统一

这个和LiveData采用了观察者模式有关,LiveData是被观察者,当数据有变化时会通知观察者(UI)。

2.减少内存泄漏

这是因为LiveData能够感知到组件的生命周期,当组件处于DESTROYED状态时,观察者对象会被清除掉。

3.当Activity停止时不会引起崩溃

这是因为组件处于非激活状态时,不会收到LiveData中数据变化的通知。

4.不需要额外的手动处理来响应生命周期的变化

这一点同样是因为LiveData能够感知组件的生命周期,所以就完全不需要在代码中告诉LiveData组件的生命周期状态。

5.组件和数据相关的内容能实时更新

组件在前台的时候能够实时收到数据改变的通知,这是可以理解的。当组件从后台到前台来时,LiveData能够将最新的数据通知组件,这两点就保证了组件中和数据相关的内容能够实时更新。

6.针对configuration change时,不需要额外的处理来保存数据

我们知道,当你把数据存储在组件中时,当configuration change(比如语言、屏幕方向变化)时,组件会被recreate,然而系统并不能保证你的数据能够被恢复的。当我们采用LiveData保存数据时,因为数据和组件分离了。当组件被recreate,数据还是存在LiveData中,并不会被销毁。

7.资源共享

通过继承LiveData类,然后将该类定义成单例模式,在该类封装监听一些系统属性变化,然后通知LiveData的观察者,这个在继承LiveData中会看到具体的例子。

二、LiveData使用

在了解LiveData定义和优点后,那它到底怎么应用呢?LiveData有几种使用方式:

  • 使用LiveData对象
  • 继承LiveData类
  • 使用LiveData对象
  • 使用LiveData对象主要有以下几个步骤:
  • 创建保存特定数据类型的LiveData实例;
  • 创建Observer对象,作为参数传入LiveData.observe()方法添加观察者;
  • 更新Livedata对象存储的数据;

三、LiveDta原理

对于某个组件的原理解析,个人现在比较习惯于从类图、时序、源码几个方面着手分析。下面的内容也是从这几点依次展开的。

LiveData的类关系图相对比较简单,从上面的类图我们就能看到。和LiveData组件相关的类和接口有:LiveData类、Observer接口、GenericLifecycleObserver接口。LiveData类是个抽象类,但是它没有抽象方法,抽象类有个特点是:不能在抽象类中实例化自己。为什么LiveData会被定义成abstract而又没有抽象方法呢,这个…我也不知道,看了下LiveData的提交记录,是在将hasObservers()替换getObserverCount()方法时将LiveData改成了abstract,在此之前它是被定义为public,可以访问外国网站的可以看下这里的修改记录

  • MediatorLiveData继承自MutableLiveData,MutableLiveData继承自LiveData。MediatorLiveData可以看成是多个LiveData的代理,当将多个LiveData添加到MediatorLiveData,任何一个LiveData数据发生变化时,MediatorLiveData都会收到通知。
  • LiveData有个内部类LifecycleBoundObserver,它实现了GenericLifecycleObserver,而GenericLifecycleObserver继承了LifecycleObserver接口。在这里可以回顾下Lifecycle组件相关的内容。当组件(Fragment、Activity)生命周期变化时会通过onStateChanged()方法回调过来。
  • Observer接口就是观察者,其中定义了LiveData数据变化的回调方法onChanged()。

四、LiveData主要涉及到的时序有三个:

  • 在Fragment/Activity中通过LiveData.observer()添加观察者(observer()方法中的第二个参数)。
  • 根据Fragment/Activity生命周期发生变化时,移除观察者或者通知观察者更新数据。
  • 当调用LiveData的setValue()、postValue()方法后,通知观察者更新数据。

如何使用Android的LiveData

使用Android的LiveData,需要在gradle添加引用:

 compile "android.arch.lifecycle:runtime:1.0.0"
 compile "android.arch.lifecycle:extensions:1.0.0"
 annotationProcessor "android.arch.lifecycle:compiler:1.0.0"

(一)使用LiveData,首先建立LiveData数据,一般继承自MutableLiveData。

MutableLiveData是LiveData的子类,添加了公共方法setValue和postValue,方便开发者直接使用。setValue必须在主线程调用。postValue可以在后台线程中调用。

本文写一个简单的MyData继承自MutableLiveData。MyData内部实现一个简单的功能,后台运行一个长时的线程任务,该线程实现一个简单功能:

(a)如果当前的Activity处于运行(用户可见)状态,则线程任务不断累计计数器并postValue一个值给任何Observer使用。

(b)如果当前Activity处于没有激活状态,则暂停线程任务,停止累计计数器。

(a)(b)两个功能由一个线程任务完成,具体实现可参见附录文章1。

在LiveData中,onActive方法回调表明当前Activity处于激活状态,也就是Activity处于生命周期的活动状态中(onStart,onResume),可以简单认为当前的Activity处于前台。

LiveData的onInactive处理涉及onActive剩下的生命周期,可以简单理解onInactive是Android的Activity/Fragment处于未激活(后台,比如当前Activity处于生命周期的onStop,onPause)。MyData.java:

package zhangphil.app; 
import android.arch.lifecycle.MutableLiveData;
import android.util.Log;
public class MyData extends MutableLiveData<String> {
 private final String TAG = "LiveData";

 private int count = 0;
 private boolean RUN = true;

 private LongTimeWork mThread = new LongTimeWork();

 public MyData() {
 mThread.start();
 }

 @Override
 protected void onActive() {
 super.onActive();
 Log.d(TAG, "onActive");

 RUN = true;
 mThread.interrupt();
 }

 @Override
 protected void onInactive() {
 super.onInactive();
 Log.d(TAG, "onInactive");

 RUN = false;
 }

 private class LongTimeWork extends Thread {
 @Override
 public void run() {
 while (true) {
 try {
 if (!RUN) {
 Thread.sleep(Long.MAX_VALUE);
 }
 } catch (Exception e) {
 e.printStackTrace();
 }

 count++;
 postValue(String.valueOf(count));

 try {
 Thread.sleep(3000);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 }
 }
 }
}

(二)构建Observer,在Observer的onChanged中等待变化数据传导过来。

在LiveData中的数据变化,通过postValue(可后台线程)或者setValue(主线程)设置后,将触发Observer的onChanged,开发者只需onChanged等待最新数据回调即可。

package zhangphil.app;

import android.arch.lifecycle.Observer;
import android.support.annotation.Nullable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

 MyObserver observer = new MyObserver();

 MyData data = new MyData();
 data.observe(this, observer);
 }

 private class MyObserver implements Observer<String> {
 @Override
 public void onChanged(@Nullable String o) {
 Toast.makeText(getApplicationContext(),String.valueOf(o),Toast.LENGTH_SHORT).show();
 }
 }
}

为什么使用LiveData构建数据通信总线LiveDataBus

一、使用LiveData的理由

  • LiveData具有的这种可观察性和生命周期感知的能力,使其非常适合作为Android通信总线的基础构件。
  • 使用者不用显示调用反注册方法。

由于LiveData具有生命周期感知能力,所以LiveDataBus只需要调用注册回调方法,而不需要显示的调用反注册方法。这样带来的好处不仅可以编写更少的代码,而且可以完全杜绝其他通信总线类框架(如EventBus、RxBus)忘记调用反注册所带来的内存泄漏的风险。

二、为什么要用LiveDataBus替代EventBus和RxBus**

  • LiveDataBus的实现及其简单 相对EventBus复杂的实现,LiveDataBus只需要一个类就可以实现。
  • LiveDataBus可以减小APK包的大小 由于LiveDataBus只依赖Android官方Android Architecture Components组件的LiveData,没有其他依赖,本身实现只有一个类。作为比较,EventBus JAR包大小为57kb,RxBus依赖RxJava和RxAndroid,其中RxJava2包大小2.2MB,RxJava1包大小1.1MB,RxAndroid包大小9kb。使用LiveDataBus可以大大减小APK包的大小。
  • LiveDataBus依赖方支持更好 LiveDataBus只依赖Android官方Android Architecture Components组件的LiveData,相比RxBus依赖的RxJava和RxAndroid,依赖方支持更好。
  • LiveDataBus具有生命周期感知 LiveDataBus具有生命周期感知,在Android系统中使用调用者不需要调用反注册,相比EventBus和RxBus使用更为方便,并且没有内存泄漏风险。

三、LiveDataBus的组成

1.消息

消息可以是任何的Object,可以定义不同类型的消息,如Boolean、String。也可以定义自定义类型的消息。

2.消息通道

LiveData扮演了消息通道的角色,不同的消息通道用不同的名字区分,名字是String类型的,可以通过名字获取到一个LiveData消息通道。

3.消息总线

消息总线通过单例实现,不同的消息通道存放在一个HashMap中。

4.订阅

订阅者通过getChannel获取消息通道,然后调用observe订阅这个通道的消息。

5.发布

发布者通过getChannel获取消息通道,然后调用setValue或者postValue发布消息。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.01.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android LiveData定义
    • 一、​为什么需要LiveData
      • 二、LiveData使用
        • 三、LiveDta原理
          • 四、LiveData主要涉及到的时序有三个:
          • 如何使用Android的LiveData
            • (一)使用LiveData,首先建立LiveData数据,一般继承自MutableLiveData。
              • (二)构建Observer,在Observer的onChanged中等待变化数据传导过来。
              • 为什么使用LiveData构建数据通信总线LiveDataBus
                • 一、使用LiveData的理由
                  • 二、为什么要用LiveDataBus替代EventBus和RxBus**
                    • 三、LiveDataBus的组成
                    相关产品与服务
                    对象存储
                    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档