EventBus 3.0 使用介绍

来源:互联网 发布:网游明星知乎 编辑:程序博客网 时间:2024/05/16 08:21

EventBus3.0(greenrobot),它是一款针对Android的发布/订阅事件总线。它可以很方便的让我们在各个组件之间,组件和线程之间进行通信,并具有很好的解耦特性。
这里写图片描述
Publisher 就是发布者、Subscriber 就是订阅者 ,它的大致流程就是:发布者发布事件给EventBus,EventBus将事件转发给注册了的订阅者。
它的优点如下:

  • simplifies the communication between components
  • decouples event senders and receivers
  • performs well with Activities, Fragments, and background threads
  • avoids complex and error-prone dependencies and life cycle issues
  • makes your code simpler
  • is fast
  • is tiny (~50k jar)
  • is proven in practice by apps with 100,000,000+ installs
  • has advanced features like delivery threads, subscriber priorities, etc.

一般的使用步骤如下:

1.使用android studio,在你项目的app目录下的build.gradle中添加对EventBus的应用

dependencies {    compile 'org.greenrobot:eventbus:3.0.0'}

2.创建自定义的event对象,这个event就是我们发布者传递给订阅者的对象,订阅者拿到这个对象后可以做一些具体的操作,这个event需要是个POJO对象:Plain Old Java Object 是指那些没有从任何类继承、也没有实现任何接口,更没有被其它框架侵入的java对象

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

3.准备订阅者,这里包含两个步骤

第一、向EventBus注册订阅者,这里使用默认的EventBus

@Overridepublic void onStart() {    super.onStart();    EventBus.getDefault().register(this); //注册,将感兴趣的订阅者传入,可以是activity,fragment等等}@Overridepublic void onStop() {   EventBus.getDefault().unregister(this); //反注册    super.onStop();}

第二、定义订阅者的回调函数

// This method will be called when a MessageEvent is posted (in the UI thread for Toast)@Subscribe(threadMode = ThreadMode.MAIN)public void onMessageEvent(MessageEvent event) { //接收MessageEvent 类型的事件,事件监听方法必须是public修饰的,如果你写成private了,则收不到消息,如果你所有的事件监听方法都不用public修饰(包括父类),则会直接报错    Toast.makeText(getActivity(), event.message, Toast.LENGTH_SHORT).show();}// This method will be called when a SomeOtherEvent is posted@Subscribepublic void handleSomethingElse(SomeOtherEvent event) { //接收SomeOtherEvent 类型的事件    doSomethingWith(event);}

4.发送事件

EventBus.getDefault().post(new MessageEvent("Hello everyone!"));//这里post是MessageEvent事件

其它须知:

one:

ThreadMode线程模式,即订阅者回调方法上面的注解,这个是3.0的新特性,通过这个线程模式可以指定回调函数是否跑在新线程@Subscribe(threadMode = ThreadMode.MAIN),默认情况下是ThreadMode: POSTING模式。

ThreadMode: POSTING:发布者post时是那个线程,那么订阅者的回调函数就在那个线程执行,因为不切换线程所以资源消耗最小
ThreadMode: MAIN:即订阅者不管发布者在哪个线程post,订阅者的回调函数都在UI 线程执行,即不能做耗时操作,容易引起ANR
ThreadMode: BACKGROUND : 如果是在UI 线程post,那么订eventbus会另起一个后台线程运行回调函数,并按顺序分发事件,只能有一个后台线程,注意不要堵塞后台线程
ThreadMode: ASYNC:不管post是在哪个线程,eventbus 都会新建一个线程执行回调函数,此时回调函数里可以做一些耗时操作,比如:网络访问,下载等,但是避免大量长时间使用异步线程

two:

配置一些特殊的EventBus对象:
前面的例子我们都是使用EventBus.getDefault()来获得一个默认的EventBus对象,然后做一些register、post这些操作,其实我们可以通过EventBusBuilder 这个类来配置一些特别的EventBus对象,比如:
正常情况下,默认的EventBus如果没有订阅者我们post事件出去时会有错误提示,但是我们可以定义一个特别的EventBus让它不提示这个错误信息,我们这样做:

EventBus eventBus = EventBus.builder().logNoSubscriberMessages(false)    .sendNoSubscriberEvent(false).build();//创建一个eventbus对象并且不提示没有订阅者的错误信息

我们也可以通过installDefaultEventBus方法,将我们的特殊配置设置到默认的EventBus里面,这样即使我们通过EventBus.getDefault()获得的对象,也具有相应的特殊性质,但是,这个设置必须在第一次使用eventbus之前配置好,不然会报异常

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

three:

粘沾性事件:Sticky Events 以sticky的形式post的最后一个事件,会保存在缓存中,待有对此事件感兴趣的订阅者时,订阅者会收到这个事件(即延迟接收)

EventBus.getDefault().postSticky(new MessageEvent("Hello everyone!"));//发送sticky事件    @Override    public void onStart() {        super.onStart();        EventBus.getDefault().register(this);    }    @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)//订阅者需要指明sticky属性才能接收    public void onEvent(MessageEvent event) {        // UI updates must run on MainThread        textField.setText(event.message);    }    @Override    public void onStop() {        EventBus.getDefault().unregister(this);        super.onStop();    }

我们还可以手动管理sticky事件

//第一种MessageEvent stickyEvent = EventBus.getDefault().getStickyEvent(MessageEvent.class);//获得sticky事件// Better check that an event was actually posted beforeif(stickyEvent != null) {    // "Consume" the sticky event    EventBus.getDefault().removeStickyEvent(stickyEvent); //处理事件后手动移除    // Now do something with it}//第二种MessageEvent stickyEvent = EventBus.getDefault().removeStickyEvent(MessageEvent.class);//获得sticky事件// Better check that an event was actually posted beforeif(stickyEvent != null) {    // Now do something with it}

four:

Priorities and Event Cancellation:优先级和取消事件,即同一个线程模式下,如果有多个订阅者订阅同一个event,那么我就可以指定订阅者收到event的优先权,即priority 其值越大优先级越高,默认为0,我们还可以在高优先级中取消事件继续向低优先级分发。

// Called in the same thread (default)@Subscribe(priority = 1); //指定优先级为1public void onEvent(MessageEvent event) {EventBus.getDefault().cancelEventDelivery(event) ; //取消事件继续向低优先级发送}

five:

Subscriber Index :订阅者索引,通过apt(Annotation Processing Tool)的方式来代替java反射找到订阅者的回调函数,大大的提升了eventbus的执行效率,具体操作如下:

//在project的build.gradle添加如下信息buildscript {    dependencies {        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'    }}//在app的build.gradle添加如下信息apply plugin: 'com.neenbedankt.android-apt'dependencies {    compile 'org.greenrobot:eventbus:3.0.0'    apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'}apt {    arguments {        eventBusIndex "com.example.admin.myeventbus.MyEventMessageindex" //这里的路径和MainActivity路径相同,MyEventBusIndex是我们自己定义的名字,    }}

配置完成后rebuild一下项目,然后会在项目的一下目录生成一个以MyEventBusIndex命名的java文件,build\generated\source\apt\debug\com\example\admin\myeventbus\MyEventMessageindex.java
MyEventBusIndex文件生成后我们就可以在项目中是用了,使用方法如下:

EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();//给项目中的eventbus添加MyEventBusIndex对象//或者将其添加到默认的eventbus中EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();// Now the default instance uses the given index. Use it like this:EventBus eventBus = EventBus.getDefault();//或者你可以添加多个索引类,这样可以实现更复杂的逻辑EventBus eventBus = EventBus.builder()    .addIndex(new MyEventBusAppIndex())    .addIndex(new MyEventBusLibIndex()).build();

six:

ProGuard:代码混淆,在AS中我们使用android自带的Proguard来混淆我们的代码,写在我们项目的app/build.gradle 文件中,一般配置如下:

    buildTypes {        release { //只有release版本才会混淆代码            // 是否进行混淆 以前使用的是runProguard true命令            minifyEnabled false            // 混淆文件的位置,其中proguard-android.txt为默认的配置文件,在SDK中,proguard-rules.pro为AS创建项目时自动生成的配置文件,我们自定义的混淆配置需要写在这个问题件中            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'        }    }

前提需要我们的sdk中包含Proguard,路径为:sdk安装目录/tools/proguard/proguard-android.txt
因为我们EventBus中订阅者的方法是回调函数,没有直接调用,所以,当我们做代码混淆时会把这些方法给删除,为了保证混淆后程序能够正常运行,我们需要配置混淆文件,让其不删除EventBus中的部分代码,配置如下,修改proguard-rules.pro文件:

-keepattributes *Annotation* //保护Annotation属性-keepclassmembers class ** { //保护指定类的成员    @org.greenrobot.eventbus.Subscribe <methods>;}-keep enum org.greenrobot.eventbus.ThreadMode { *; } //保护指定的类文件和类的成员# Only required if you use AsyncExecutor-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {    <init>(java.lang.Throwable);}

http://greenrobot.org/eventbus/
https://github.com/greenrobot/EventBus

0 0