EventBus 开源库学习(二)

EventBus开源库使用流程源码解析
本文对EventBus开源库使用流程进行源码解析,版本为3.3.1。使用步骤包括注册、解注册、编写事件处理函数和事件发送。详细分析了注册、解注册、事件发送post及粘性事件发送postSticky的源码逻辑,如注册时建立订阅关系,解注册时移除相关数据等。

整体流程阅读

EventBus在使用的时候基本分为以下几步:
1、注册订阅者

EventBus.getDefault().register(this);

2、订阅者解注册,否者会导致内存泄漏

EventBus.getDefault().unregister(this);

3、在订阅者中编写注解为Subscribe的事件处理函数

@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 1)
public void onMsgEventReceived(MsgEvent event) {
   
   
     Toast.makeText(this, event.getMsg(), Toast.LENGTH_LONG).show();
}

4、事件发送

EventBus.getDefault().post("msg1 - coming!!!");

我们先按使用的流程大体看下源码逻辑,源码版本3.3.1:

注册源码逻辑

    public static EventBus getDefault() {
   
   
        EventBus instance = defaultInstance;
        if (instance == null) {
   
   
            synchronized (EventBus.class) {
   
   
                instance = EventBus.defaultInstance;
                if (instance == null) {
   
   
                    instance = EventBus.defaultInstance = new EventBus();
                }
            }
        }
        return instance;
    }

EventBus 使用了双重校验锁的单例设计模式,保证用到的对象是唯一的,首次使用对象为空的时候通过下面构造创建一个。

    public EventBus() {
   
   
        this(DEFAULT_BUILDER);
    }

DEFAULT_BUILDER是一个final常量,在加载的时候就进行初始化,赋一个EventBusBuilder对象如下面代码所示。

private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();

EventBusBuilderEventBus的建造类,里面参数在加载的时候进行了初始化。

public class EventBusBuilder {
   
   
    private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();

    boolean logSubscriberExceptions = true;
    boolean logNoSubscriberMessages = true;
    boolean sendSubscriberExceptionEvent = true;
    boolean sendNoSubscriberEvent = true;
    boolean throwSubscriberException;
    boolean eventInheritance = true;
    boolean ignoreGeneratedIndex;
    boolean strictMethodVerification;
    ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
    List<Class<?>> skipMethodVerificationForClasses;
    List<SubscriberInfoIndex> subscriberInfoIndexes;
    Logger logger;
    MainThreadSupport mainThreadSupport;
    ...
}

如果有需要的话,我们也可以通过配置EventBusBuilder来更改EventBus的属性,在EventBus中有一个静态方法直接返回一直新的EventBusBuilder对象,设置完参数后调用build()来以新的配置来新建一个EventBus对象。

#EventBus
    public static EventBusBuilder builder() {
   
   
        return new EventBusBuilder();
    }

#EventBusBuilder
    /** Builds an EventBus based on the current configuration. */
    public EventBus build() {
   
   
        return new EventBus(this);
    }

然后通过下面的调用来设置:

EventBus.builder()
        .eventInheritance(false)
        .logSubscriberExceptions(false)
        .build()
        .register(this);

拿到EventBus对象以后,我们可以调用其register方法进行订阅者注册了。

    public void register(Object subscriber) {
   
   
        Class<?> subscriberClass = subscriber.getClass();
        List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
        synchronized (this) {
   
   
            for (SubscriberMethod subscriberMethod : subscriberMethods) {
   
   
                subscribe(subscriber, subscriberMethod);
            }
        }
    }

首先获取订阅者类subscriber,然后通过findSubscriberMethods方法获取该类中以@Subscribe注解的函数,由于一个类中可能监听多个事件,因此获取的方法可能是多个,所有的方法赋值到一个List列表中,然后遍历这个列表进行注册。

    private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
   
   
        Class<?> eventType = subscriberMethod.eventType;
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
   
   
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
   
   
            if (subscriptions.contains(newSubscription)) {
   
   
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }

        int size = subscriptions.size();
        for (int i = 0; i <= size; i++) {
   
   
            if (i =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值