[Android开发] EventBus3 使用方法教程总结

来源:互联网 发布:php 类魔术方法 编辑:程序博客网 时间:2024/06/06 00:50

一、EventBus是啥?

EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通讯,比如网络请求,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。

Github地址:
https://github.com/greenrobot/EventBus

二、使用步骤

2.1 添加jar包

在build.gradle里面添加

compile 'org.greenrobot:eventbus:3.0.0'

2.2 注册

在需要接收消息的activity里面进行注册

EventBus.getDefault().register(MainActivity.this);

2.3 解注册

对应的activity销毁了就解注册EventBus,释放内存

/** * 解注册EventBus */@Overrideprotected void onDestroy() {    super.onDestroy();    EventBus.getDefault().unregister(MainActivity.this);}

2.4 构造发送信息类

新建一个类,这里取名为MessageEvent,用来做消息的传递。 这个类可以是自定义或者你用String这些也行,发送和接收的类型一定要一致才能接收到

/** * EventBus发送信息类 */public class MessageEvent {    String name;    public MessageEvent(String name) {        this.name = name;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

2.5 发布消息

这个post的参数类型一定要和接收消息的类型一致

public void sendEventBusMessage(){    EventBus.getDefault().post(new MessageEvent("天平"));}

2.6 接收消息

在注册了的activity里面编写方法接收消息,必须加注解Subscribe,threadMode在下面会说到。 接收消息的方法名没有限制。

/** * 5.接收消息,需要加注解Subscribe订阅者 * @param bean 自定义的消息类,根据这个类标识来接收 */@Subscribe(threadMode = ThreadMode.MAIN)public void receiverEvenetBusMess(MessageEvent bean){    //显示接收到的消息    Toast.makeText(this,bean.getName()+"",Toast.LENGTH_SHORT).show();}

三、粘性事件

前面所说的使用方法都是需要先注册register,再post,才能接收到事件;如果你使用postSticky发送事件,那么可以不需要先注册,你先postSticky之后,再注册也能接收到事件。

3.1 构造发送信息类

public class StickyMessageEvent {    int age;    public StickyMessageEvent(int age) {        this.age = age;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }}

3.2 发布消息

public void sendStickyEventBusMessage(){    EventBus.getDefault().postSticky(new StickyMessageEvent(20));}

3.3 接收消息

/** * 接收粘性事件,sticky为true * @param bean 接收到的消息 */@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)public void receiverStickyMess(StickyMessageEvent bean){    tvResult.setText(bean.getAge()+"");    Toast.makeText(this,bean.getAge()+"",Toast.LENGTH_SHORT).show();}

3.4 注册
3.5 解注册

注册和解注册和上面的一致

四、注解参数

在接收的方法上面需要添加注解来接收消息,注解可以添加的参数有三个

4.1 threadMode

线程模式,接收消息的你这个方法是不是在线程,在注解上面标识:

/** * 5.接收消息,需要加注解Subscribe订阅者,参数类型必须和发送时候类型一致才能接收, * @param bean */@Subscribe(threadMode = ThreadMode.MAIN)public void receiverEvenetBusMess(MessageEvent bean){    //显示接收到的消息    Toast.makeText(this,bean.getName()+"",Toast.LENGTH_SHORT).show();    tvResult.setText(bean.getName());}

有四种消息类型
1. ThreadMode.MAIN
表示这个方法在主线程中执行,不能处理耗时任务噢,一般用来更新UI,因为更新ui需要在ui线程中。。。。

  1. ThreadMode.BACKGROUND
    当事件是在UI线程发出,那么事件处理实际上是新建了一个单独线程回调,如果是在后台线程发出,那么事件处理就在该线程。该事件处理方法应该是快速的,避免阻塞后台线程。

  2. ThreadMode.ASYNC
    无论事件在哪个线程发布,都会创建新的子线程在执行,发送事件方不需要等待事件处理完毕。这种方式适用于该事件处理方法需要较长时间,例如网络请求。

  3. ThreadMode.POSTING (注解不设置的threadMode的话,默认就是这个模式)
    消息在哪个线程发布出来的,接收的方法就会在这个线程中运行,也就是说发布事件和接收事件线程在同一个线程。使用这个方法时,在onEvent方法中不能执行耗时操作,如果执行耗时操作容易导致事件分发延迟。

4.2 sticky粘滞性

是否是粘性,默认值为假。在粘性事件用到,接收方法的注解上面需要添加这个参数为true,才能收到消息。例如:

/** * 接收粘性事件,sticky为true * @param bean 接收到的消息 */@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)public void receiverStickyMess(StickyMessageEvent bean){    tvResult.setText(bean.getAge()+"");    Toast.makeText(this,bean.getAge()+"",Toast.LENGTH_SHORT).show();}

4.3 priority优先级

优先级,默认值为0,就是你有多个接收的方法,这时候你可以指定接收的顺序,添加参数priority。值越大,越先收到,从大到小 依次接收。例如:

    /**     * 5.接收消息,需要加注解Subscribe订阅者,参数类型必须和发送时候类型一致才能接收,     * @param bean     */    @Subscribe(threadMode = ThreadMode.MAIN,priority = 0)    public void receiverEvenetBusMess(MessageEvent bean){        //显示接收到的消息        //Toast.makeText(this,bean.getName()+"111",Toast.LENGTH_SHORT).show();        tvResult.setText( tvResult.getText() + "\n" + bean.getName() + "000");    }    @Subscribe(threadMode = ThreadMode.MAIN,priority = 2)    public void receiverEvenetBusMessTwo(MessageEvent bean){        //显示接收到的消息        //Toast.makeText(this,bean.getName()+"222",Toast.LENGTH_SHORT).show();        tvResult.setText( tvResult.getText() + "\n" + bean.getName() + "222");    }    @Subscribe(threadMode = ThreadMode.MAIN,priority = 1)    public void receiverEvenetBusMessThree(MessageEvent bean){        //显示接收到的消息        //Toast.makeText(this,bean.getName()+"222",Toast.LENGTH_SHORT).show();        tvResult.setText( tvResult.getText() + "\n" + bean.getName() + "111");    }

上面的代码输出结果是:

天平222天平111天平000

五、使用建议

5.1 消息类型的定义

创建一个事件类,把你的每一个参数(或者可能发生冲突的参数),封装成一个类:

public class EventBean  {      public static class UserListEvent {          public List<User> users;      }    public static class ItemListEvent {          public List<Item> items;      }    } 

5.2 性能优化

按照Markus Junginger的说法(EventBus创作者),在3.0中,如果你想进一步提升你的app的性能,需要在build.gradle添加:

provided 'de.greenrobot:eventbus-annotation-processor:3.0.0'

其在编译的时候为注册类构建了一个索引,而不是在运行时,这样的结果是其让EventBus 3.0的性能提升了一倍,相比2.4来说,其会是它的3到6倍。

5.3 混淆

-keepattributes *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/documentation/proguard/

1 0