EventBus

简介

一款针对Android优化的发布/订阅事件总。

项目地址

https://github.com/greenrobot/EventBus

特点

  • 简化了组件之间的传递消息,将发送者和接收者解耦,同时避免了依赖性和生命周期问题。
  • 使你的代码更加简化
  • 小(~50k)
  • 在很多的app中使用
  • 有高级功能,比如线程间传递,订阅优先级等

gradle配置

compile 'org.greenrobot:eventbus:3.0.0'

使用

定义事件
public static class MessageEvent { /* Additional fields if needed */ }
声明订阅者

声明你的订阅方法

@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {/* Do something */};

注册和注销订阅者

@Override
public void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}

@Override
public void onStop() {
    super.onStop();
    EventBus.getDefault().unregister(this);
}
发送订阅者
EventBus.getDefault().post(new MessageEvent());

知识点

1.threadMod四种模式,默认是ThreadMode: POSTING

ThreadMode: MAIN ,事件的处理会在UI主线程中执行,不应处理耗时的事件。

ThreadMode: BACKGROUND , 事件的处理会在一个BackgroundPoster后台线程中执行,虽然是后台线程但是有个处理队列。当一个处理耗时事件时可能会处理阻塞的情况。

ThreadMode: POSTING ,事件的处理在和事件的发送在相同的进程。

ThreadMode: ASYNC ,每个事件都会创建一个线程。

2.priority优先级,默认是0

优先级高的先处理,前提是在同一个线程中。比例下面的代码就有可能优先级失效。

    @Subscribe(priority=1,threadMode = ThreadMode.ASYNC)
    public void onPriority1(MessageEvent event){
        Logger.d("onEventData priority=1");
    }

    @Subscribe(priority=2,threadMode = ThreadMode.ASYNC)
    public void onPriority2(MessageEvent event){
        Logger.d("onEventData priority=2");
    }

    @Subscribe(priority=3,threadMode = ThreadMode.ASYNC)
    public void onPriority3(MessageEvent event){
        Logger.d("onEventData priority=3");
    }

    @Subscribe(priority=4,threadMode = ThreadMode.ASYNC)
    public void onPriority4(MessageEvent event){
        Logger.d("onEventData priority=4");
    }

    @Subscribe(priority=5,threadMode = ThreadMode.ASYNC)
    public void onPriority5(MessageEvent event){
        Logger.d("onEventData priority=5");
    }
3.sticky粘性,默认是false

预发送广播,如果有订阅者直接接收广播,如果没有等有可以接收粘性广播的订阅者还是可以接收到广播,如果不取消掉会一直存在。

发送粘性广播

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

取消粘性广播

EventBus.getDefault().removeStickyEvent();

源代码分析

初始化设置
  • EventBus.installDefaultEventBus():创建默认的EventBus,只能创建一次
  • EventBuilder.addIndex():增加索引
  • EventBuilder.eventInheritance():是否订阅父类中的方法,默认是true
  • EventBuilder.executorService():设置线程池。
  • EventBuilder.ignoreGeneratedIndex():忽略索引
  • EventBuilder.logNoSubscriberMessages():打印没有订阅方法,默认是true
  • EventBuilder.logSubscriberExceptions():打印订阅异常,默认true
  • EventBuilder.sendNoSubscriberEvent():在没有订阅的情况下不发送,默认true
  • EventBuilder.sendSubscriberExceptionEvent():发送订阅中的异常,默认false
  • EventBuilder.skipMethodVerificationFor():忽略对该类的方法验证
  • EventBuilder.strictMethodVerification():是否启用严格的方法检查
  • EventBuilder.throwSubscriberException():是否抛出异常
初始化EventBus

EventBus的默认defaultInstance实例。
这里可以通过EventBusBuilder构建多个EventBus,而且构建的每个EventBus都是相互隔离的。

public class EventBus {

    ....

    static volatile EventBus defaultInstance;

    private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();

    ....
    /** Convenience singleton for apps using a process-wide EventBus instance. */
    public static EventBus getDefault() {
        if (defaultInstance == null) {
            synchronized (EventBus.class) {
                if (defaultInstance == null) {
                    defaultInstance = new EventBus();
                }
            }
        }
        return defaultInstance;
    }

   /**
     * Creates a new EventBus instance; each instance is a separate scope in which events are delivered. To use a
     * central bus, consider {@link #getDefault()}.
     */
    public EventBus() {
        this(DEFAULT_BUILDER);
    }
    ...
    EventBus(EventBusBuilder builder) {
        subscriptionsByEventType = new HashMap<>();
        typesBySubscriber = new HashMap<>();
        stickyEvents = new ConcurrentHashMap<>();
        mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
        backgroundPoster = new BackgroundPoster(this);
        asyncPoster = new AsyncPoster(this);
        indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
        subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
                builder.strictMethodVerification, builder.ignoreGeneratedIndex);
        logSubscriberExceptions = builder.logSubscriberExceptions;
        logNoSubscriberMessages = builder.logNoSubscriberMessages;
        sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
        sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
        throwSubscriberException = builder.throwSubscriberException;
        eventInheritance = builder.eventInheritance;
        executorService = builder.executorService;
    }
}
注册订阅者
EventBus:register()
    ||
    ||加载订阅方法
    ||
SubscriberMethodFinder:findSubscriberMethods()
    ||
    ||先获取方法缓存,然后判断是否强制反射获取订阅的方法遍历List<SubscriberMethod>
    ||
EventBus:subscribe()
    ||
    ||生成Subscription对象并对方法进行排序,如果是sticky对预发送广播进行处理
    ||
发送广播
EventBus:post()或者postSticky()
    ||
    ||发送广播,如果是sticky加入到stickyEvents列表中
    ||设置发送的isMainThread和isPosting,判断canceled
    ||
EventBus:postSingleEvent()
    ||
    ||检查是否关闭eventInheritance,这里关闭就不会去检查父类的方法,可以以提高速度,默认是开着的
    ||
EventBus:postSingleEventForEventType()
    ||
    ||获取订阅的方法发送广播
    ||
EventBus:postToSubscription()
    ||
    ||通过threadMode分别处理,直接调用方法或者进入相对应的队列中
    ||
EventBus:invokeSubscriber()
    ||
    ||调用方法
    ||

\

results matching ""

    No results matching ""