设为首页 加入收藏

TOP

EventBus 使用/架构/源码分析(一)
2019-08-30 06:18:07 】 浏览:58
Tags:EventBus 使用 架构 源码 分析

EventBus是针对Android优化的发布-订阅事件总线,简化了Android组件间的通信。EventBus以其简单易懂、优雅、开销小等优点而备受欢迎。

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

1. 使用

1.1 gradle中引入

        api 'org.greenrobot:eventbus:3.0.0'

1.2 定义事件

定义一个类作为事件,可以在类中定义不同的参数,发布者赋值,订阅者取值。
public class TestEvent {

    private String mName;


    public TestEvent(String name) {
        mName = name;
    }

    public String getEventName() {
        return mName;
    }
}
 
 

1.3 注册事件

首先需要将当前对象(Activity/Fragment等)与EventBus绑定(一般在onCreate函数中进行注册)

EventBus.getDefault().register(this);

接收事件的函数:

@Subscribe (threadMode = ThreadMode.MAIN, sticky = true)
public void onTestKeyEvent(TestEvent event) {
        Log.d(TAG, "onTestKeyEvent | eventName=" + event.getEventName());
        Toast.makeText(this, "test event, name=" + event.getEventName(), Toast.LENGTH_SHORT).show();
    }

这里通过注解的方式,定义事件的类型,和回调的线程等信息。

查看EventBus jar包中Subscribe定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    
ThreadMode
 threadMode() default ThreadMode.POSTING;

    /**
     * If true, delivers the most recent sticky event (posted with
     * {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
     */
    boolean 
sticky
() default false;

    /** Subscriber priority to influence the order of event delivery.
     * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
     * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
     * delivery among subscribers with different {@link ThreadMode}s! */
    int 
priority
() default 0;
}

 

查看EventBus jar包中ThreadMode定义:

a) POSTING : 回调在发布者线程

b) MAIN : 回调在主线程

c) BACKGROUND : 回调在子线程(如果发布在子线程者回调直接运行在该线程)

d) ASYNC : 异步回调(不回回调在发布线程也不会回调在主线程)

 

1.4 发送事件

发布者不需要进行注册,只需要将事件post出去。

a)  普通事件:EventBus.getDefault().post(new TestEvent("normalEvent"));

b) 粘性事件:EventBus.getDefault().postSticky(new TestEvent("stickEvent"));

 

普通事件和粘性事件区别:

     如果发布的是普通事件,当前如果没有Subscriber,则后续注册的Subscriber也不会收到该事件。

     如果发布的是粘性事件,当前如果没有Subscriber,内部会暂存该事件,当注册Subscriber时,该Subscriber会立刻收到该事件。

 

2. 结构

EventBus-Publish-Subscribe

采用了典型的订阅发布设计模式。

3. 源码分析

// 这里只分析其原理和结构不会细细推敲每一行代码

订阅者信息封装(Subscription):

定义了两个成员变量,

final Object subscriber;  // 订阅一个事件的对象
final SubscriberMethod subscriberMethod; // 订阅的具体信息(方法名/ThreadMode/isStrick/priority)

EventBus主要成员变量:

private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
private final Map<Object, List<Class<?>>> typesBySubscriber;
private final Map<Class<?>, Object> stickyEvents;

subscriptionsByEventType:以event(即事件类)为key,以订阅列表(Subscription)为value,事件发送之后,在这里寻找订阅者,而Subscription又是一个CopyOnWriteArrayList,这是一个线程安全的容器。你们看会好奇,Subscription到底是什么,其实看下去就会了解的,现在先提前说下:Subscription是一个封装类,封装了订阅者、订阅方法这两个类。
typesBySubscriber:以订阅者类为key,以event事件类为value,在进行register或unregister操作的时候,会操作这个map。
stickyEvents:保存的是粘性事件

 

3.1 注册Subscriber

注册过程,也就是调用regester函数的执行过程(主要是通过反射将注册者信息添加到上述讲的两个map中:typesBySubscriber、subscriptionsByEventType

regeister_

a) SubscriberMethodFinder 是专门用来查找目标对象中所有订阅函数(带缓存,避免同一个类多次反射
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android根据word模板文档将表单数.. 下一篇Android仿QQ复制昵称效果2

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目