【android】EventBus原理

在公司实习,小组的项目使用到这个框架,尽管一直在使用,很顺手很好用,但是不怎么明白里面的原理,赶着最近准备找工作,总结一下吧。

EventBus–ReadMe

必然要先从官方文档开始,最然看不怎么懂,但是看看官方的总结还是很有用的。

EventBus is a publish/subscribe event bus optimized for Android.

EventBus 是一个针对Android优化的发布/订阅的事件总线

img

EventBus…

  • simplifies the communication between components

    简化组件之间的通信

    • decouples event senders and receivers

    分离事件的发送者和接收者

    • performs well with Activities, Fragments, and background threads

    在Activity、Fragment以及后台线程上表现良好

    • avoids complex and error-prone dependencies and life cycle issues

    避免复杂和容易出错的依赖和生命周期问题

  • makes your code simpler

    牛逼

  • is fast

    牛逼

  • is tiny (~50k jar)

    牛逼

  • is proven in practice by apps with 100,000,000+ installs

    牛逼

  • has advanced features like delivery threads, subscriber priorities, etc.

    具有传送线程、观察者优先级等高级功能

EventBus in 3 steps

使用只需要三步哦

  1. Define events:

    定义 event

    public static class MessageEvent { /* Additional fields if needed */ }
  2. Prepare subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:

    准备观察者(或者叫做订阅者):声明和注释你的订阅方法,可选地指定线程模式

    @Subscribe(threadMode = ThreadMode.MAIN)  //比如这个就指定主线程
    public void onMessageEvent(MessageEvent event) {/* Do something */};

    Register and unregister your subscriber. For example on Android, activities and fragments should usually register according to their life cycle:

    register()unregister()你的订阅者。举个栗子:在Android里,acticity和fragment应该在它们的生命周期里做这些工作。

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }
    
    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }
  3. Post events:

    发送 event

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

Add EventBus to your project

Via Gradle:

compile 'org.greenrobot:eventbus:3.0.0'

Via Maven:

<dependency>
    <groupId>org.greenrobotgroupId>
    <artifactId>eventbusartifactId>
    <version>3.0.0version>
dependency>

Or download the latest JAR from Maven Central.

EventBus的历史版本变化

eventbus 3.0.0 开始不再规定订阅者的订阅方法名:

原来的订阅方法要遵守如下命名:

  • onEvent
  • onEventMainThread
  • onEventBackgroundThread
  • onEventAsync

现在可以由自己随意命名,但必须加上注解,加注解方式像上面ReadMe里那样,不加注解会抛出RunTimeException

原理分析

1、EventBus.getDefault()

看到这个,很容易想到单例模式。

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

果真,还是个懒汉式单例。

再看构造方法:

    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;
    }

构造了几个HashMap,用来存放各种订阅者信息的。其中有几个有点熟悉的成员:mainThreadPosterbackgroundPosterasyncPoster。看起来像是注解的时候的线程。没错,他们就是post()的时候用到的,用于将event在不同的线程发出去,达到在不同的线程中执行的效果。

  • mainThreadPoster: 是一个自定义的Handler,在构造的时候传入的是主线程的Looper,所以它是一个主线程对应的Handler。
  • backgroundPoster: 这个final类实现了Runnable接口,很显然用于某个线程。
  • asyncPoster: 这个类实现了Runnable接口。

上面三个对象有两个共同的代码:

eventBus.invokeSubscriber(pendingPost):使用反射调用订阅者的事件方法。

eventBus.getExecutorService().execute(this):把事件交给空闲的线程去执行。

2、register()和post()

画了一张图
【android】EventBus原理_第1张图片
这里有一篇好博客

你可能感兴趣的:(android)