对源码的阅读不多,从用的比较多的EventBus开始,还是有些看不懂的地方。
最常用的写法:
EventBus.getDefault().register(this);
EventBus.getDefault().unregister(this);
EventBus.getDefault().post("hello");
@Subscribe
public void mainEvent(MessageEvent messageEvent) {
if(messageEvent.getmStrMessage().equals(CommonEventMessage.LOGINED)) {
mIMainView.updateMessage();
}
}
1.EventBus.getDefault().register(this);
1.1 getDefault():
/** 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;
}
这里就是一个单例的模式:首先直接做null的判断操作,如果为null了才去进行同步锁的操作,保证了性能。
接下来是加入了同步锁,防止多线程的干扰,但在
defaultInstance = new EventBus();
这里会产生一个问题,就是重排序的问题,当前这个已经进入的线程在进行实例化的时候,会发生三件事:
- 给 instance 分配内存
- 调用 Singleton 的构造函数来初始化成员变量
- 将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)
但是由于指令重排序,2和3的步骤可能发生颠倒,所以要对defaultInstance添加volatile关键字来避免这种情况:
static volatile EventBus defaultInstance;
1.2 register()
/**
* Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
* are no longer interested in receiving events.
* <p/>
* Subscribers have event handling methods that must be annotated by {@link Subscribe}.
* The {@link Subscribe} annotation also allows configuration like {@link
* ThreadMode} and priority.
*/
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
if (ignoreGeneratedIndex) {
subscriberMethods = findUsingReflection(subscriberClass);
} else {
subscriberMethods = findUsingInfo(subscriberClass);
}
if (subscriberMethods.isEmpty()) {
throw new EventBusException("Subscriber " + subscriberClass
+ " and its super classes have no public methods with the @Subscribe annotation");
} else {
METHOD_CACHE.put(subscriberClass, subscriberMethods);
return subscriberMethods;
}
}
利用反射去查找当前类是否有接收订阅的方法,如果没有的话,则会抛出一个错误异常出来。然后把查找出来的方法进行一次遍历,然后添加订阅。
2.EventBus.getDefault().unregister(this)
/** Unregisters the given subscriber from all event classes. */
public synchronized void unregister(Object subscriber) {
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);
} else {
logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
参考
如何正确地写出单例模式
秒懂,Java 注解 (Annotation)你可以这样学
深入浅出反射