前言:在以前的项目里面一直用的是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 的视图,等等。
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的简单使用介绍了。
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.运行速度的不同:(借鉴的某个文章的图 表示感谢)
可以看出,EventBus3.0使用索引加速后,性能飙升了很多。
1.使用广播(BroadCastReciver):
使用广播的代码臃肿(还有一种说法:它们内部的实现都需要IPC,单从传递效率上来讲,可能并不太适合上层的组件间通信),而且Intent传递数据时,在编译时并不能检查出所设的extra类型与收到时的类型一致。所以一个很常见的错误便是你或者你团队中的其他人改变了Intent所传递的数据,但忘记了对全部的接收器(receiver)进行更新。这种错误在编译时是无法被发现的,只有在运行时才会发现问题。
2.使用startActivityForResult()和onActivityResult()方法:
startActivityForResult和onActivityResult,会产生较多的状态或逻辑判断,而且Intent或Bundle传值还得检测类型,容易发生错误。更复杂些的场景,比如A启动B,B启动C,在C中用户的操作需要更新A和B,那么判断逻辑就更麻烦了。
over,到此两者的比较就结束了。