个人博客:haichenyi.com。感谢关注
简介
我们先来看一下他的类注释
/**
* EventBus is a central publish/subscribe event system for Android. Events are posted ({@link #post(Object)}) to the
* bus, which delivers it to subscribers that have a matching handler method for the event type. To receive events,
* subscribers must register themselves to the bus using {@link #register(Object)}. Once registered, subscribers
* receive events until {@link #unregister(Object)} is called. Event handling methods must be annotated by
* {@link Subscribe}, must be public, return nothing (void), and have exactly one parameter
* (the event).
*
* @author Markus Junginger, greenrobot
*/
英语不是很好,大致讲一下这段话是什么意思:EventBus是重要的发布/订阅的Android事件系统。事件被发布给总线,这个总线将这个事件传递给跟他匹配类型的订阅者。接收事件必须在总线使用的时候注册他们。一旦注册,订阅者就会一直接收事件,直到他们被取消注册。这个接收方法必须增加注解Subscribe标识,必须是public,返回类型是void,并且只有一个参数。 简单的来说,就是用之前必须先注册,然后接收方法必须有Subscribe注解,必须是public,返回类型是void并且只有一个参数
简单用法
第一步:依赖
implementation 'org.greenrobot:eventbus:3.1.1'
第二步:注册与反注册
//注册,在onCrate里面
EventBus.getDefault().register(this)
//反注册,在onDestory里面
EventBus.getDefault().unregister(this)
第三步:接收方法
@Subscribe
public void handle(MyClothes myClothes){
//你的具体逻辑
}
第四步:发送
EventBus.getDefault().post(new MyClothes())
经过上面三步,你就可以正常使用EventBus了,前面两步要在一个类里面,因为接收之前,必须要注册,可以在任意的地方post
源码解析—getDefault()
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
可以看到这里使用的是双重校验锁的单例模式,保证不同的线程调用该方法得到的都是同一个EventBus实例。
EventBus()
看到上面的单例模式之后,我们再来瞅瞅单例模式里面调用的构造方法
public EventBus() {
this(DEFAULT_BUILDER);
}
这里他的空参数的构造方法里面调用的是一个参数的构造方法,我们来看看这个参数是什么?
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
EventBusBuilder()
EventBusBuilder() {
}
这个builder的构造方法里面什么都没有,也就是说没有初始化任何变量,那我们看一看他的变量,这里我就说一个:
private final static ExecutorService DEFAULT_EXECUTOR_SERVICE = Executors.newCachedThreadPool();
ExecutorService executorService = DEFAULT_EXECUTOR_SERVICE;
Executors.newCachedThreadPool() 创建的是一个可缓存的线程池,如果线程池长度超过处理需要,可灵活回收空线程池,若无回收,可新建线程。
接下来,我们再来看看只有EventBusBuilder参数的构造方法
EventBus(EventBusBuilder builder)
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
...
}
讲到这里,很明显,他这里用的是建造者模式,跟我们之前讲的Luban的模式是一样的,这个建造者模式,我就不讲了。讲Luban的时候讲过的
这里我列出来的6个变量,其他变量并没有列出来,因为,其他变量都是builder里面的赋值,没有啥好讲的。我们来看看这6个成员变量的类型
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
private final Map<Object, List<Class<?>>> typesBySubscriber;
private final Map<Class<?>, Object> stickyEvents;
private final Poster mainThreadPoster;
private final BackgroundPoster backgroundPoster;
private final AsyncPoster asyncPoster;
意义:
- subscriptionsByEventType:可以看到这是一个是以event的class为key,以subscribe的list为value的map,有的人可能不知道CopyOnWriteArrayList,这是ArrayList的一个线程安全变种。(这里,有人会点到Subscription里面去看一下,可以看到就是一个类,封装了订阅者和订阅方法,重写了hashcode和equal方法)
- typesBySubscriber:这是以订阅者类为key,以event的list为value的map,在注册和反注册的时候用的到
- stickyEvents:粘性事件,以event的class为key,订阅者为value的map
- 后面这三个Poster都是用来处理粘性事件的
我们说了这么多成员变量。我们知道这里的EventBusBuilder就是给EventBus初始化成员变量的,辣么,我们可不可以不用getDefault,获取eventBus对象呢?
EventBus build1 = EventBus.getDefault();
EventBus build2 = EventBus.builder().build();
这两个build的区别是什么呢?我们可以点到build()方法里面去看一下:
public EventBus build() {
return new EventBus(this);
}
他这里是直接new出来的,并没有单例,所以每次使用的都是new一个新的对象,而通过getDefault,获得是同一个对象
网友评论