概述
EventBus基于安卓优化的发布-订阅事件总线,本质上还是Java的观察者模式。消息接收者注册到Bus总线,消息发送后根据相应的消息类型分发消息。
总的注册和消息发送流程如下
源码解读
观察者注册
使用单例模式新建唯一EventBus实例
public static EventBus getDefault() { EventBus instance = defaultInstance; if (instance == null) { synchronized (EventBus.class) { instance = EventBus.defaultInstance; if (instance == null) { instance = EventBus.defaultInstance = new EventBus(); } } } return instance; }
注册观察者
public void register(Object subscriber) { Class<?> subscriberClass = subscriber.getClass();//获取观察者的类 List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);//使用反射拿到观察者类所有的监听对象 synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { subscribe(subscriber, subscriberMethod);//订阅该对象和它的所有方法 } } }
订阅的时候按监听方法参数分类缓存到Bus总线
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { ... Class<?> eventType = subscriberMethod.eventType; Subscription newSubscription = new Subscription(subscriber, subscriberMethod); ... }
消息发送
消息发送者通过post发送消息
public void post(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; eventQueue.add(event); if (!postingState.isPosting) { postingState.isMainThread = isMainThread(); postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { postSingleEvent(eventQueue.remove(0), postingState);//发送事件 } } finally { postingState.isPosting = false; postingState.isMainThread = false; } } }
拿到消息发送者发送消息的类型
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass();//重点在这里,按消息类型发送到相应的对象 boolean subscriptionFound = false; if (eventInheritance) { List<Class<?>> eventTypes = lookupAllEventTypes(eventClass); int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { logger.log(Level.FINE, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } }
使用反射方法的invoke方法唤起观察者的监听方法
void invokeSubscriber(Subscription subscription, Object event) { try { subscription.subscriberMethod.method.invoke(subscription.subscriber, event);//最后用反射唤起对象的监听方法 } catch (InvocationTargetException e) { handleSubscriberException(subscription, event, e.getCause()); } catch (IllegalAccessException e) { throw new IllegalStateException("Unexpected exception", e); } }
反注册
根据观察者的类型移除事件总线中相应的观察者对象
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()); } }
总结
- 由于使用注解,在实际业务开发中可能定位Bug有困难
- 使用方便,比Handler和广播方便
- 关键代码使用反射,性能可能有所下降