EventBus和Otto的故事

前言:在以前的项目里面一直用的是EventBus在页面间发送传递事件替代从而替代经典的广播的使用,但是在新的项目里小伙伴选择了使用Otto,既然是合作嘛我也就看了一下Otto的使用方式就直接开始使用Otto了。这几天抽时间看了一下行业技术的情况,发现EventBus和Otto是解耦框架的主流,大家基本都是使用的这个两个的其中一个,所以整理了一下他们的特性和差异。

友情提示,该篇的主要目的是介绍EventBus和Otto的对比而不是他们的使用和原理!!!

开头先把两个框架诞生的原因给贴出来:

EventBus和Otto框架的主要功能是帮助我们来降低多个组件通信之间的耦合度的(解耦)。

比如:由界面 A 跳转到界面 B ,然后点击 B 中的 button, 现在要更新 界面 A 的视图。再比如:界面有一个 界面 A,A 里面的有个 Fragment,点击 Fragment 中的一个 button,跳转到界面 B, 点击界面 B的 button 要更新界面 A 的 Fragment 的视图,等等。

一:先来简单的看看EventBus怎么用。

1.添加库依赖

compile 'org.greenrobot:eventbus:3.0.0'

2.自定义一个消息事件类(这个类就是一个Bean类,里面定义用来传输的数据的类型

public class MessageEvent{
    private String message;
    public  MessageEvent(String message){
        this.message=message;
    }
    public String getMessage() {
        return message;
    }
 
    public void setMessage(String message) {
        this.message = message;
    }
}

3.注册接收事件(当我们需要在Activity或者Fragment里订阅事件时,我们需要注册EventBus。一般在onCreate()方法里去注册EventBus

@Override
protected void onCreate(Bundle savedInstanceState) {           
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     EventBus.getDefault().register(this);
}

4.解除注册事件(一般在onDestory()方法里,去解除注册

@Override
protected void onDestroy() {
    super.onDestroy();
    EventBus.getDefault().unregister(this);
}

5.发送需要的事件

EventBus.getDefault().post(messageEvent);

6.注解接收方法对指定的事件处理

@Subscribe(threadMode = ThreadMode.MAIN)
public void XXX(MessageEvent messageEvent) {
    ...
}

好了,EventBus的简单使用就是这么简单了,接下来就是Otto的简单使用介绍了。

二:再来看看Otto是怎么使用的。(流程和EventBus使用基本一致,所以下面写的简单了

1.添加依赖库

compile 'com.squareup:otto:1.3.8'

2.创建AppBus单例,提高效率

public class AppBus extends Bus {

    private static AppBus bus;

    private AppBus() {
    }

    public static AppBus getInstance() {
        if (bus == null) {
            bus = new AppBus();
        }
        return bus;
    }
}

3.创建事件数据类(就是bean)

public class PlusOneText {
    public PlusOneText(String name) {
        this.name = name;
    }

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4.在数据接收页面—订阅,取消订阅,接收数据

  AppBus.getInstance().register(this);
AppBus.getInstance().unregister(this);

    @Subscribe
    public void setContext(PlusOneText plusOneText) {
        // 处理plusOneText数据
    }

好了,Otto的使用也是这么简单。

三:最后说说两者之间的对比和差异吧。

1.获取对象方式不同:

两者的构造方法都是public的,可以自由创建对象,但是通常情况,我们希望使用一个对象即可,所以会封装成单例的。
EventBus提供了单例的实现。通过EventBus.getDefault()获取,而Otto的Bus类需要自己封装成单例。

2.参数设置的不同:

从设计方面来说,EventBus提供了更自由的控制,由EventBusBuilder来封装参数并创建对象,以后扩展参数,就扩展Builder类即可,不用改动目标类。Bus的参数设置是通过构造方法注入的,以后如果需要扩展参数,则需要扩展Bus的构造方法,不是很方便。

3.支持跨线程的不同:

EventBus支持订阅方法在不同线程中执行,通过@Subscribe的ThreadMode指定,由于支持跨线程,就可以很方便的替代类似Handler+Thread的异步交互方式。当子线程中的任务完成后,直接发送事件更新UI等。

Otto没有像EventBus那样强大实现了4种ThreadMode,Otto中在接口ThreadEnforcer提供了ANY和MAIN,在MAIN内部有一个是否是主线程的检查,而ANY不做任何检查的事情。因此Otto更多的使用场景是在主线程中,相对是轻量级的。

4.订阅方法的继承支持的不同:

EventBus3.0查询订阅方法时,会从父类中查找,而Otto只会查找当前类中的订阅方法。也就是说,在父类中定义的订阅方法,Otto是没法接收事件的。

5.订阅方法参数的限制的不同:

两者都支持事件的继承关系,比如事件类ChildEvent继承于FatherEvent,发送ChildEvent事件,则订阅了FatherEvent的方法也可以接收到。EventBus3.0还支持接口,比如ChildEvent实现了接口EventInterface,发送ChildEvent事件,订阅了EventInterface的方法也可以接收到,而Otto是不支持接口的。
6.运行速度的不同:(借鉴的某个文章的图 表示感谢)

EventBus和Otto的故事_第1张图片

可以看出,EventBus3.0使用索引加速后,性能飙升了很多。

四:以他们和原生组件通信的对比作为结尾。

1.使用广播(BroadCastReciver):

使用广播的代码臃肿(还有一种说法:它们内部的实现都需要IPC,单从传递效率上来讲,可能并不太适合上层的组件间通信),而且Intent传递数据时,在编译时并不能检查出所设的extra类型与收到时的类型一致。所以一个很常见的错误便是你或者你团队中的其他人改变了Intent所传递的数据,但忘记了对全部的接收器(receiver)进行更新。这种错误在编译时是无法被发现的,只有在运行时才会发现问题。

2.使用startActivityForResult()和onActivityResult()方法:

startActivityForResult和onActivityResult,会产生较多的状态或逻辑判断,而且Intent或Bundle传值还得检测类型,容易发生错误。更复杂些的场景,比如A启动B,B启动C,在C中用户的操作需要更新A和B,那么判断逻辑就更麻烦了。

over,到此两者的比较就结束了。

see  you 

你可能感兴趣的:(学无止境)