都在说EventBus,我也来一波EventBus

最近在了解android一些使用较多的开源库,偶然听到了EventBus这个东西,去greenrobot/EventBus看一下,嗯,官方文档写的都很简单明了,所以在这里用我蹩脚的英语翻译一下,当然,还是会加上点自己的小白文,嘻嘻。这里我不整篇翻译,我只翻译一些对我自己有用的(其实是有些东西不太懂害羞)。开始!

EventBus是什么

EventBus是对Android进行优化的发布/订阅事件总线。上张官方的图。

都在说EventBus,我也来一波EventBus_第1张图片

觉得官方这张图把EventBus的流程真是解释的非常nice~。首先EventBus里面有两个角色,发布者Publisher和订阅者Subscriber,发布者发布事件post(),经过EventBus处理,分发delivery给订阅者,订阅者在onEvent()方法中接收事件。这里我先举一个应用场景。假设我们有两个activity(A、B)。通常我们在finish掉一个activity(B)的时候,如果要通知上一个activity(A)发生了变化,一般会在A重写onActivityResult方法,如果使用EventBus的时候,你可以在A注册成为订阅者,那么你就可以在B 发布事件,B此时便为发布者,A便可以接收到事件。

有人可能会说,并没有啥卵用啊感觉,看下文。

EventBus的好处

1.简化组件之间的通信。
(1).解耦发送者和接受者
(2).可以在activity、fragment以及后台线程很好的执行
(3).避免了容易出错、复杂的依赖以及生命周期的问题。
2.使你的代码更加简洁
3.快速
4.体积小(jar包小于50k)
5.在一个超过一亿安装量的app上实践过
6.还有一些更高级的功能,如线程分发、订阅者优先级、等等。

添加依赖(AS用户)

compile 'de.greenrobot:eventbus:2.4.0'


如何使用EventBus(3步)

1.定义事件

事件是一个没有其他指定要求的POJO(Java原生对象)。看这篇博客的我指定为你有一定的编程基础,我这里就不解释什么是POJO了。
public class MessageEvent {
    public final String message;

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

2.准备订阅者(subscribers)

订阅者需要实现一个事件处理方法onEvent()用于接收事件。同时订阅者需要注册或者解除注册到总线中。下面以activity作为订阅者为例。
    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

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

    // This method will be called when a MessageEvent is posted
    public void onEvent(MessageEvent event){
        Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();
    }

    // This method will be called when a SomeOtherEvent is posted
    public void onEvent(SomeOtherEvent event){
        doSomethingWith(event);
    }

3.发布事件

你可以在任何地方发布你的事件,所有订阅者将根据发布事件的类型来接收事件。
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));

线程分发以及线程模式(Delivery threads and ThreadModes)

EventBus可以为你处理线程:事件接收的线程可以与发布事件的线程不同。
一个常见的使用场景就是处理UI的变化。在android中,改变UI必须在主线程中。另一方面,网络任务或者其他耗时的任务,不能在主线程中运行。EventBus可以帮你处理这些耗时任务并且同步到UI线程中去(你不用深入研究线程之间的转换或者使用AsyncTask,等等)。
在EventBus中,你可以通过使用 ThreadMode去定义一个将会调用事件处理函数OnEvent的线程:

PostThrad:订阅者将会在和发布者同一线程被调用。这是默认行为。同时这也是开销耗费最少的行为,因为它避免了线程之间的转换。所以如果你知道你的任务耗费的时间非常少,同时不一定要在主线程中完成,那么将推荐使用这种模式。订阅者使用这种模式必须尽快返回以避免阻塞可能是主线程的发布者线程。例子:
// 在同一个线程调用 (默认)
    public void onEvent(MessageEvent event) {
        log(event.message);
    }

MainThread:订阅者将在android的主线程中被调用 。如果发布者是在主线程中,那么事件处理方法将被直接调用。订阅者使用这种方式必须尽快返回以避免阻塞主线程。 例子:
// 在主线程中被调用
    public void onEventMainThread(MessageEvent event) {
        textField.setText(event.message);
    }
BackgroudThread:订阅者将在子线程被调用。如果发布者的线程不是主线程,那么订阅者将直接在发布者的线程被调用。如果发布者的线程是主线程,那么EventBus将使用一条单独的子线程来顺序地处理它的所有事件。订阅者使用这种模式必须尽快返回结果以避免阻塞子线程。
// 在子线程中被调用
    public void onEventBackgroundThread(MessageEvent event){
        saveToDisk(event.message);
    }

Async:订阅者将会在单独的一条线程中被调用。这条线程总是独立于发布者的线程以及主线程。使用这种模式发布事件不会等待事件处理方法的返回。如果你的事件处理方法需要耗费很长时间,那么订阅者需要使用这种模式,例如,访问网络。为了限制并发线程的数量,你要避免在同一时间内使用大量的异步处理方法。因为EventBus内部使用了一个线程池来有效率的回收那些异步任务完成的线程。
 //在单独的线程中被调用
    public void onEventAsync(MessageEvent event){
        backend.send(event.message);
    }

注意:EventBus将会根据订阅者的方法名在相应的线程中去执行(OnEvent、OnEventAsync 等等)。

订阅者优先级以及事件分发顺序(Subscribers priorities and ordered event delivery)

你可以改变事件分发的顺序通过在注册订阅者的时候给它提供一个优先级。

int priority = 1;
EventBus.getDefault().register(this, priority);

如果在相同的线程模式中(即上面提到的四种ThreadMode),priority比较高的将会比priority较低的先接收到事件。默认的priority是0.
注意:在不同的ThreadMode中,priority的大小并不会影响订阅者接收事件的顺序。

取消事件分发

你可以通过在订阅者的事件处理方法中调用cancelEventDelivery(Object event)来取消事件的分发。所有将在之后进行的事件将被取消:后续的订阅者将不会接收到事件。

// Called in the same thread (default)
    public void onEvent(MessageEvent event){
        // Process the event 
        ...

        EventBus.getDefault().cancelEventDelivery(event) ;
    }

通常在较高优先级的订阅者事件处理方法中使用。cancelEventDelivery只能在发布者的线程中调用( ThreadMode.PostThread)

其他功能以及注意的地方


不基于注解

查找注解在adnroid中是非常慢的,特别在android4.0以前,看一看下面这个链接 Android bug report (看你妹啊,这是墙外链接。而且最新的EventBus3.0也添加了注解,仿佛在打自己脸,还要提供证据)

Base on Convention(不知道怎么翻译,基于约定?)

事件处理方法叫做“OnEvent()”

高性能

或许是android中最快的事件总线(魅族,可能比苹果好看一点点?)

方便的单例模式

你可以通过调用EventBus.getDefault()来获得一个可以处理很多东东的事件总线实例。你也可以通过new EventBus()来创建任意数量的实例。

订阅者以及事件继承

事件处理方法接收的参数可以是事件的超类,然后事件会被发布到事件的超类的处理者中,包括被事件实现的接口。例如,订阅者可以注册Object类型的事件来接收所有EventBus发送的事件。
这段我知道翻译的有点绕,以下原文,各位看官请自定脑补。

Event handler methods may be defined in super classes, and events are posted to handlers of the event's super classes including any implemented interfaces. For example, subscriber may register to events of the type Object to receive all events posted on the event bus.

FAQ

Q:EventBus跟BroadcastReceiver以及android的Intent有啥子区别?
A:不同于BroadcastReceiver以及Intent,EventBus使用了标准的Java类来作为事件以及提供了大量方便的API。EventBus在于避免大量使用场景如:非常麻烦地设置Intent,准备Intent Extras,实现BroadcastReceiver以及提取上一个activity发送过来的数据。当然,EventBus只需要非常小的开销。


好累啊,后面的那些东西感觉目前对我来说没什么卵用,以后我用到了再来补充吧,有兴趣的也可以去看。混淆配置什么的。。。

End~!




你可能感兴趣的:(android,框架,EventBus,库,事件总线)