您的位置:首页 > 其它

EventBus 3.0 从入门到精通——使用详解(一)

2017-07-13 17:43 465 查看
文章索引:

EventBus 3.0 从入门到精通——初识EventBus

EventBus 3.0 从入门到精通——EventBus的应用场景

EventBus 3.0 从入门到精通——使用详解(一)

EventBus 3.0 从入门到精通——使用详解(二)

本文参考EventBus官网,有兴趣的朋友可以直接上官网阅读:http://greenrobot.org/eventbus/documentation/

EventBus 3.0 三步走

在开始使用EventBus3.0之前,必须先引入EventBus3.0(ps:那是当然了。。。),方法如下:

Gradle

compile 'org.greenrobot:eventbus:3.0.0'


Maven

<dependency>
<groupId>org.greenrobot</groupId>
<artifactId>eventbus</artifactId>
<version>3.0.0</version>
</dependency>


第一步:定义事件

事件是没有具体返回值的POJO(普通的Java类)。

public class MessageEvent {

public final String message;

public MessageEvent(String message) {
this.message = message;
}
}


(PS:据我所知事件类是可以继承的,并且对于事件内的属性也是可以被继承的,这样的好处就是开发人员可以通过继承更好的组织一类事件,注意在继承时,发布子类的事件父类订阅者能够接收到消息,而发布父类的事件子类的订阅者不能接收到事件

第二步:准备订阅者

订阅者需要实现事件处理方法(或者叫做“订阅者方法”),这个方法会在一个事件被发布之后调用。事件处理方法需要通过
@Subscribe
注解定义。注意: EventBus3.0的事件处理方法的名称可以自由选择(没有像EventBus2那种命名约束)

// 当MessageEvent事件被发布的时候这个方法将会调用。(因为使用了Toast所以会在UI线程调用)
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
}

// 当SomeOtherEvent事件被发布的时候这个方法将会调用
@Subscribe
public void handleSomethingElse(SomeOtherEvent event) {
doSomethingWith(event);
}


订阅者必须在总线(EventBus)上注册和反注册它自己。因为只有订阅者注册之后才会收到事件消息。在Android系统上,在Activites和Fragments组件中通常使用它们的生命周期方法来注册订阅者。并且在大多数情况下onStart/onStop两个方法会更好。

@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}

@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}


第三步:发布事件

可以在代码中的任何地方发布一个事件。所有符合事件类型并且当前已经注册的订阅者都会接收到事件。

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));


通过以上的代码,发布事件后,所有的通过
@Subscribe
注解声明的订阅者如果符合事件
MessageEvent
就会接收到消息。

消息传输线程(线程模式)

EventBus能够替你处理线程:事件可以在发布线程以外的线程中传输。一般情况下事件可以用来处理UI改变。在Android系统上,必须在UI线程(或者叫main线程)中更新UI。而另一方面,网络和任何耗时的任务,都必须不能再UI线程中执行。EventBus能够帮助你处理这些耗时任务和UI线程同步(不必去专研线程同转换和使用AsyncTask)。

使用EventBus,你可以给事件处理方法的调用线程定义四种线程模式。

ThreadMode: POSTING

这种线程模式的订阅者会在与发布者相同的线程中被调用。注意:这种模式是默认的。 也就是说在不设置线程模式的情况下,订阅者被调用的线程和发布者的线程是一个线程。 一旦事件发送完成,事件同步就会完成并且所有的订阅者都会被调用(订阅当前事件的订阅者)。因为这种线程模式完全避免了线程转换,所以它是性能开销最小的线程模式。因此这种模式被推荐用于执行事件短并且不需要调用main线程的简单任务。使用这种线程模式来处理事件应该快速返回避免阻碍发布线程(因为发布线程和订阅者事件处理逻辑在一个线程,如果处理事件过长,发布线程会阻塞,尤其避免在UI线程发布事件后订阅者长时间不返回结果,会造成ANR)。

// 在相同线程被调用 (默认)
// 线程模式在这里设置
@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessage(MessageEvent event) {
log(event.message);
}


ThreadMode: MAIN

这种模式下订阅者会在main线程被调用(一般情况下指的是UI线程)。如果发布线程是main线程,那么事件处理方法会被直接调用(就像使用ThreadMode.POSTING描述一样)。事件处理者如果使用这种模式必须快速返回以免阻塞UI线程。

// Called in Android UI's main thread
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessage(MessageEvent event) {
textField.setText(event.message);
}


ThreadMode: BACKGROUND

订阅者会在后台线程被调用。如果发布线程不是main线程,事件处理方法会直接在发布线程中调用。如果发布线程不是main线程,EventBus会使用一个单一线程按照顺序发送所有的事件。事件处理者如果使用这种模式应该尽量快速返回,避免阻塞后台线程(PS:因为后台线程只有一个,并且是顺序执行的,耗时的事件处理,会造成队列积压)。

// Called in the background thread
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessage(MessageEvent event){
saveToDisk(event.message);
}


ThreadMode: ASYNC

这种模式下事件处理者会在一个独立线程中被调用。这个线程独立于main线程和发布线程。使用这种模式,发布事件不用等待事件处理者。如果事件处理方法执行需要一些事件,例如网络接入。应该使用这种模式。避免触发大量长时间运行的异步处理方法同时也要限制同一时间的线程数量。EventBus使用了一个线程池用来把已经处完成的异步处理消息线程有效的重新利用。

// Called in a separate thread
@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessage(MessageEvent event){
backend.send(event.message);
}


配置

EventBusBuilder类可以配置EventBus的多个方面。例如:以下的配置就可以在发布事件遇到没有订阅者的情况下不做任何处理。

EventBus eventBus = EventBus.builder()
.logNoSubscriberMessages(false)
.sendNoSubscriberEvent(false)
.build();


另一个例子:当订阅者抛出异常的时候程序不会被EventBus捕获。

EventBus eventBus = EventBus.builder().throwSubscriberException(true).build();


注意 默认情况下EventBus会缓存事件处理者的异常并发布一个
SubscriberExceptionEvent
事件,但是并不一定需要处理这个事件。

点击EventBusBuilder class and its JavaDoc 查看所有的可配置项。

配置默认的EventBus实例

使用
EventBus.getDefault()
是一个在App任何代码中获取EventBus对象实例的简便方式。EventBusBuilder同样准许配置默认的EventBus实例通过
installDefaultEventBus()
方法。

举个例子:我们可以配置默认的EventBus实例去重新抛出订阅者事件处理方法的异常。但是因为这种异常很像是App的crash所以最好只在DEBUG版本中使用。

EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).installDefaultEventBus();


注意 这种设置只在默认的实例被第一次使用前才能生效。随后调用
installDefaultEventBus()
会抛出异常。这样可以保证在你的App中EventBus动作保持一致。Application 类是在第一次使用前配置EventBus的一个好地方。

今天先到这里未完待续。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  应用 阅读