EventBus介绍与简单使用

EventBus介绍:

     EventBus出自greenrobot,和之前大名鼎鼎的GreenDao出自同一家。今天我们将学习分析Event 3.0,EventBus 3.0 最新的特性就是加入了注解,通过注解的方式 告知订阅函数运行在哪个线程中,是一种发布订阅设计模式(观察者设计模式)。

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

     官方文档:http://greenrobot.org/eventbus/documentation

EventBus主要角色:

  •  Event 传递的事件对象
  •  Subscriber  事件的订阅者 
  •  Publisher  事件的发布者
  •  ThreadMode 定义函数在何种线程中执行

  官网给出的各种角色的协作图

  • EventBus底层采用的是注解和反射的方式来获取订阅方法信息(首先是注解获取,若注解获取不到,再用反射)
  • 当前订阅者是添加到Eventbus 总的事件订阅者的subscriptionByEventType集合中
  • 订阅者所有订阅的事件类型添加到typeBySubscriber 中,方便解注册时,移除事件

EventBus介绍与简单使用_第1张图片

EventBus功能: 通过解耦发布者和订阅者简化Android事件传递,EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函数,在Fragment,Activity,Service线程之间传递数据,执行方法。

EventBus优缺点:

优点:简化组件之间的通信方式,实现解耦让业务代码更加简洁,可以动态设置事件处理线程以及优先级

缺点:目前发现唯一的缺点就是类似之前策略模式一样的诟病,每个事件都必须自定义一个事件类,造成事件类太多,无形中加大了维护成本

EventBus示例:

 1.)build.gradle添加引用 
compile 'org.greenrobot:eventbus:3.0.0'
2.)订阅/解除订阅

 订阅

EventBus.getDefault().register(this);//订阅

 解除订阅

EventBus.getDefault().unregister(this);//解除订阅

3.)定义一个事件类型

/**
 * 传递事件实体类(EventBus发送此类事件给订阅者)
 */
1
2
3
4
5
6
7
8
9
10
11
   
public class EventBusMessage {    
     
     //定义了发送的消息必须是String.
     
       public String Message;
     
       public EventBusMessage(String message) {
     
           Message = message;
     
 }
4.)发布事件
使用EventBus发送事件,使用Post方法,参数也必须是EventBus消息对且要和接收的保持一致
EventBus.getDefault().post(new EventBusMessage());
5.)订阅事件处理
 
   
/**
 * 声明订阅方法:当接收到事件的时候,会调用该方法
 * 使用@Subscribe注解
 * */
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(EventBusMessage msg) {
    Log.d("eventBusThread", "ThreadMode.MAIN " + Thread.currentThread().getName());
}
ThreadMode总共四个:
  • NAIN UI主线程
  • BACKGROUND 后台线程
  • POSTING 和发布者处在同一个线程
  • ASYNC 异步线程
接收消息,参数就是你定义的EventBus消息类,和发送消息类必须是同一个
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    加注解提示:在写接收消息的方法是,方法名可以自定义,权限必须是public,
    参数必须是一个只要接收的参数类型是一致的,那么四个方法都可以接收到发送的信息  
    ThreadMode.MAIN表示这个方法在主线程中执行 (适合做异步加载,可以将子线程加载到数据直接设置到UI界面里)*/    
     
    @Subscribe(threadMode = ThreadMode.MAIN)
     
    public void onEvent(EventBusMessage msg){
     
       //在TextView显示接收的消息,从这个类里拿属性.
     
       tv_title.setText(msg.Message);
     
       Log.d("eventBusThread","ThreadMode.MAIN "+Thread.currentThread().getName());
     
    }
     
     
    //ThreadMode.POSTING表示该方法和消息发送方在同一个线程.
     
    @Subscribe(threadMode = ThreadMode.POSTING)
     
    public void onEvent(EventBusMessage msg){
     
       Log.d("eventBusThread","ThreadMode.POSTING "+Thread.currentThread().getName());
     
    }
     
     
    /*ThreadMode.ASYNC也表示在后台执行(也就是子线程执行),可以异步并发处理
     
    (适用于多个线程任务处理,内部有线程池管理,比如请求网络时,用这个方法,他会自动创建线程去请求)
     
    无论发布者是在子线程还是主线程,该方法都会创建一个子线程,在子线程执行.*/
     
    @Subscribe(threadMode = ThreadMode.ASYNC)
     
    public void onEvent(EventBusMessage msg){
     
       Log.d("eventBusThread","ThreadMode.ASYNC "+Thread.currentThread().getName());
     
    }
     
     
    //ThreadMode.BACKGROUND表示该方法在后台运行(也就是子线程),不能够并发处理
     
    //如果发布者在子线程,那么该方法就在子线程执行
     
    //如果发布者在主线程,那么该方法就会创建一个子线程,在子线程运行.
     
    @Subscribe(threadMode = ThreadMode.BACKGROUND)
     
    public void onEvent(EventBusMessage msg){
     
       Log.d("eventBusThread","ThreadMode.BACKGROUND "+Thread.currentThread().getName());
     
    }
通过控制台所打印出来的线程名输出数据:
在主线程发送事件 在子线程发送事件
main: 主线程 主线程
posting: 主线程 子线程
background: 新开一个子线程 子线程
async: 新开一个子线程 新开一个子线程
6.)终止事件往下传递

 发送有序广播可以终止广播的继续往下传递,EventBus也实现了此功能

  EventBus.getDefault().cancelEventDelivery(event) ;//优先级高的订阅者可以终止事件往下传递

EventBus黏性事件

概念: 黏性事件就是指在EventBus内部被缓存的那些事件

原理: EventBus为每个类(class)类型保存了最近一次被发送的事件——sticky。后续被发送过来的相同类型的sticky事件会自动替换之前缓存的事件。当一个监听者向EventBus进行注册时,它会去请求缓存事件。这时,缓存的事件就会立即自动发送给这个监听者,有一定的延时性.

EventBus除了普通事件也支持粘性事件,这个有点类似广播分类中的粘性广播。本身粘性广播用的就比较少,为了方便理解成订阅在发布事件之后,但同样可以收到事件。订阅/解除订阅和普通事件一样,但是处理订阅函数有所不同,需要注解中添加sticky = true,是启动黏性事件

1
2
3
4
    @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void EventBusSticky(EventBusStickyMessage eventBusStickyMessage){    
        tv_title.setText(eventBusStickyMessage.message);
    }

发送粘性事件


EventBus.getDefault().postSticky(new EventBusStickyMessage()); 

如果不需要黏性事件我们可以移除

EventBus.getDefault().removeStickyEvent(new EventBusStickyMessage());

或者调用移除所有粘性事件

  EventBus.getDefault().removeAllStickyEvents();

你可能感兴趣的:(帮助)