软件工程大二学生一枚,对Android的理解不是很透彻,若有失误希望大家指正,谢谢大家。
动机
在使用EventBus
的时候,觉得比较好用,所以就准备去看源码。本文主要介绍了EventBus
怎么实现的(从设计思想到每一行代码)。
什么是EventBus
总结为以下几点:
- EventBus是一个发布 / 订阅(
Subscriber
/Publisher
)的事件总线,内部是靠Handler
发送Message
来进行通信的。 - EventBus不是基于注解的,基于命名规定的,即以“onEvent”开头的。
- 事件驱动
- EventBus可以在多线程下订阅消息。
上面这几点,下面都会一一解释的。
先看一段EventBus的简单使用代码:
//SubscriberActivity
public class SubscriberActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_subscriber);
EventBus.getDefault().register(this);
}
public void onEvent(Event aEvent)
{
//do something with aEvent
}
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
}
//PublisherActivity
//可以在任意地方调用
EventBus.getDefault().post(new Event());
构造EventBus
在EventBus
源码文件夹里面,首先可以看到2个类,EventBus
与EventbusBuilder
。
EventBus
定义了所有的入口方法;
EventbusBuilder
利用Builder模式来构造EventBus
。
上述例子中,调用了下面的方法:
static volatile EventBus defaultInstance;
/**
* 双重同步锁,利用单例模式(Singleton)构造一个EventBus对象
*/
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
进入EventBus
的构造函数:
public EventBus() {
this(DEFAULT_BUILDER);
}
/**
* 一大推参数暂时不解释,等哈在讲
* @param 为一个EventBusBuilder对象
*/
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<Class<?>, CopyOnWriteArrayList<Subscription>>();
typesBySubscriber = new HashMap<Object, List<Class<?>>>();
stickyEvents = new ConcurrentHashMap<Class<?>, Object>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
subscriberMethodFinder = new SubscriberMethodFinder(builder.skipMethodVerificationForClasses);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
EventBusBuilder
类里面:
/**
* Installs the default EventBus returned by {@link EventBus#getDefault()} using this builders' values. Must be
* done only once before the first usage of the default EventBus.
*
* @throws EventBusException if there's already a default EventBus instance in place
*/
public EventBus installDefaultEventBus() {
synchronized (EventBus.class) {
if (EventBus.defaultInstance != null) {
throw new EventBusException("Default instance already exists." +
" It may be only set once before it's used the first time to ensure consistent behavior.");
}
EventBus.defaultInstance = build();
return EventBus.defaultInstance;
}
}
/** Builds an EventBus based on the current configuration. */
public EventBus build() {
return new EventBus(this);
}
典型的构造者模式,不必多说,可以参见Notification
及NotificationBuilder
来学习。
我们可以通过以下方式来创建EventBus
对象:
EventBus.getDefault();
- 通过
EventBusBuilder
自行定制参数,再来创建。
Poster
上文说到:EventBus是一个发布 / 订阅(Subscriber/Publisher)的事件总线。那么Subscriber
Publisher
之间怎么联系,就要用到了Poster
。
Poster
有以下几种:
HandlerPoster
BackgroundPoster
AsyncPoster
重点介绍HandlerPoster
,其他2个差不多。
Step1:先看看PendingPost
final class PendingPost {
////单例池,复用对象
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event; //事件类型(就是onEvent(Event aEvent)里面这个参数的类型)
Subscription subscription; //订阅者的封装类
PendingPost next; //指向队列下个元素的指针
private PendingPost(Object event, Subscription subscription) {