EventBus的使用
EventBus的优点:代码简洁,使用简单,并将事件发布和订阅充分解耦
- 定义事件Event
- 准备订阅者
- 订阅者同时需要在总线上订阅和注销自己
- 发送事件(可以在代码的任何地方)
implementation 'org.greenrobot:eventbus:3.1.1'
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void updateList(UpdateMessageEvent event) {
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
EventBus.getDefault().post(new UpdateMessageEvent());
EventBus对象的创建
/** Convenience singleton for apps using a process-wide EventBus instance.
DoubleCheck的单例模式*/
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
//ThreadLocal 线程内部的存储类,可以在指定的线程中存储数据,存储完之后只能在
//指定的线程中才能获取到数据
private final ThreadLocal<PostingThreadState> currentPostingThreadState = new ThreadLocal<PostingThreadState>() {
@Override
protected PostingThreadState initialValue() {
return new PostingThreadState();
}
};
/**
*EventBus在代码中有多条总线 ,订阅者可以注册到不同的EventBus上,用不同的EventBus来发送数据。不同的EventBus发送数据是相互隔离开的
*/
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
// event为Key ,Subscription 为value
subscriptionsByEventType = new HashMap<>();
//Subscriber 为Key,Event为value
typesBySubscriber = new HashMap<>();
//粘性事件
stickyEvents = new ConcurrentHashMap<>();
mainThreadSupport = builder.getMainThreadSupport();
// 三个post负责线程间的调度
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
//后台线程的 方法
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
//Event 事件的索引
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
//对设置Subscribe注解方法的找寻器
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
//异常信息打印
logSubscriberExceptions = builder.logSubscriberExceptions;
//没有订阅者订阅信息的时候是否打印日志
logNoSubscriberMessages = builder.logNoSubscriberMessages;
//调用事件处理函数时异常是否需要发送SubscriberExceptionEvent 事件
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
//当没有事件处理函数时,对事件处理是否需要发送NoSubscriberEvent
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
//是否需要抛出异常
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
//线程池
executorService = builder.executorService;
}
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);
}
}
public class HandlerPoster extends Handler implements Poster {
/**
*存放即将执行post事件的队列
*/
private final PendingPostQueue queue;
//post事件能在HandleMessage中存在的最大时间数
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
//handler 是否运行起来了
private boolean handlerActive;
protected HandlerPoster(EventBus eventBus, Looper looper, int maxMillisInsideHandleMessage) {
super(looper);
this.eventBus = eventBus;
this.maxMillisInsideHandleMessage = maxMillisInsideHandleMessage;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
}
}
}
@Override
public void handleMessage(Message msg) {
boolean rescheduled = false;
try {
long started = SystemClock.uptimeMillis();
while (true) {
// 开启循环,在队列中获取数据
PendingPost pendingPost = queue.poll();
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
//分发事件
eventBus.invokeSubscriber(pendingPost);
long timeInMethod = SystemClock.uptimeMillis() - started;
//需要判断时间
if (timeInMethod >= maxMillisInsideHandleMessage) {
if (!sendMessage(obtainMessage())) {
throw new EventBusException("Could not send handler message");
}
rescheduled = true;
return;
}
}
} finally {
handlerActive = rescheduled;
}
}
}
final class PendingPost {
//通过ArrayList提供两个方法 来提供对象的读写和删除
private final static List<PendingPost> pendingPostPool = new ArrayList<PendingPost>();
Object event;
Subscription subscription;
PendingPost next;
private PendingPost(Object event, Subscription subscription) {
this.event = event;
this.subscription = subscription;
}
//获取PendingPost
static PendingPost obtainPendingPost(Subscription subscription, Object event) {
}
//回收PendingPost
static void releasePendingPost(PendingPost pendingPost) {
}
}
final class BackgroundPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
private volatile boolean executorRunning;
BackgroundPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!executorRunning) {
executorRunning = true;
eventBus.getExecutorService().execute(this);
}
}
}
@Override
public void run() {
try {
try {
//不断的从队列中获取消息
while (true) {
PendingPost pendingPost = queue.poll(1000);
if (pendingPost == null) {
synchronized (this) {
// Check again, this time in synchronized
pendingPost = queue.poll();
if (pendingPost == null) {
executorRunning = false;
return;
}
}
}
//事件分发
eventBus.invokeSubscriber(pendingPost);
}
} catch (InterruptedException e) {
eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interruppted", e);
}
} finally {
executorRunning = false;
}
}
}
class AsyncPoster implements Runnable, Poster {
private final PendingPostQueue queue;
private final EventBus eventBus;
AsyncPoster(EventBus eventBus) {
this.eventBus = eventBus;
queue = new PendingPostQueue();
}
public void enqueue(Subscription subscription, Object event) {
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
queue.enqueue(pendingPost);
eventBus.getExecutorService().execute(this);
}
@Override
public void run() {
//只获取队列中的一个PendingPost
PendingPost pendingPost = queue.poll();
if(pendingPost == null) {
throw new IllegalStateException("No pending post available");
}
//事件分发
eventBus.invokeSubscriber(pendingPost);
}
}
EventBus @Subscribe 注解
@Documented
@Retention(RetentionPolicy.RUNTIME)//指定可以在运行时有效
@Target({ElementType.METHOD})//用来描述方法
public @interface Subscribe {
//线程模式
ThreadMode threadMode() default ThreadMode.POSTING;
//是否是粘性事件 事件消费者在事件发送之后才注册的也能接收该事件的特殊类型
boolean sticky() default false;
//优先级
int priority() default 0;
}
public enum ThreadMode {
/**
*EventBus 中默认的线程模式,在执行post事件操作的时候,线程会直接调用订阅者的方法,不论该线程是否在主线程,在主线程中不能执行耗时操作
*/
POSTING,
/**
* 在主线程中执行这个方法
*/
MAIN,
/**
*UI thread the event will always be queued for delivery. This ensures that the post call is non-blocking.
*/
MAIN_ORDERED,
/**
*后台线程执行这个方法,如果发布线程不是在主线程中,不能直接调用订阅者的事件处理函数,需要启动唯一的后台线程去处理
*/
BACKGROUND,
/**
*无论发布线程是否在主线程,都会使用空线程去处理,不会出现线程卡顿
*/
ASYNC
}
EventBus的订阅
final class Subscription {
// 订阅者
final Object subscriber;
final SubscriberMethod subscriberMethod;
volatile boolean active;
Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
active = true;
}
}
public void register(Object subscriber) {
//通过反射获取订阅者的Class对象
Class<?> subscriberClass = subscriber.getClass();
//通过获取到的Class对象找到订阅者方法的集合
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
//可并发读写的ArrayList
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
//没有注册过
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
//遍历集合,根据优先级添加到指定位置的集合中
subscriptions.add(i, newSubscription);
break;
}
}
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
subscribedEvents.add(eventType);
// 是否是粘性事件
if (subscriberMethod.sticky) {
//是否支持继承关系
if (eventInheritance) {
//
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
//是否有继承关系
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
//分发事件
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
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;
}
}
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
FindState findState = prepareFindState();
//赋值操作
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
//获取订阅者信息
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) {
//获取到订阅方法的集合
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();
for (SubscriberMethod subscriberMethod : array) {
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {
//将订阅方法添加到集合中
findState.subscriberMethods.add(subscriberMethod);
}
}
} else {
findUsingReflectionInSingleClass(findState);
}
//找寻父类
findState.moveToSuperclass();
}
//资源回收,
return getMethodsAndRelease(findState);
}
//判断订阅好的方法是否可以添加到订阅者集合当中
boolean checkAdd(Method method, Class<?> eventType) {
Object existing = anyMethodByEventType.put(eventType, method);
if (existing == null) {
return true;
} else {
if (existing instanceof Method) {
if (!checkAddWithMethodSignature((Method) existing, eventType)) {
// Paranoia check
throw new IllegalStateException();
}
// Put any non-Method object to "consume" the existing Method
anyMethodByEventType.put(eventType, this);
}
//根据方法签名进行检查,不要出现一个订阅者有多个相同方法订阅同一个事件
return checkAddWithMethodSignature(method, eventType);
}
}
private FindState prepareFindState() {
synchronized (FIND_STATE_POOL) {
//遍历查找FindState值
for (int i = 0; i < POOL_SIZE; i++) {
FindState state = FIND_STATE_POOL[i];
if (state != null) {
FIND_STATE_POOL[i] = null;
return state;
}
}
}
return new FindState();
}
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// 通过反射获取到订阅者的所有方法
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
//获取到方法修饰符
int modifiers = method.getModifiers();
//方法是否为public 方法修饰符是否可以忽略
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
//获取到方法的参数
Class<?>[] parameterTypes = method.getParameterTypes();
//方法参数长度只能为1
if (parameterTypes.length == 1) {
//过滤出由Subscribe 注解修饰的方法
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
//创建SubscriberMethod对象,添加到集合中
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException("@Subscribe method " + methodName +
"must have exactly 1 parameter but has " + parameterTypes.length);
}
} else if (strictMethodVerification && method.isAnnotationPresent(Subscribe.class)) {
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
throw new EventBusException(methodName +
" is a illegal @Subscribe method: must be public, non-static, and non-abstract");
}
}
}
public class SubscriberMethod {
//订阅的方法
final Method method;
//线程的模式
final ThreadMode threadMode;
//事件的类型
final Class<?> eventType;
//方法的优先级
final int priority;
//是否为粘性事件的标志位
final boolean sticky;
/** 方法名 */
String methodString;
public SubscriberMethod(Method method, Class<?> eventType, ThreadMode threadMode, int priority, boolean sticky) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.priority = priority;
this.sticky = sticky;
}
}
- 判断是否有注册该事件
- 然后再按照优先级加入到subscriptionsByEventType(是一个HashMap)的value的List中
- 然后再添加到typesBySubscriber(是一个HashMap)的value的List中
- 分发事件:checkPostStickyEventToSubscription
EventBus 的事件分发
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;
}
}
}
//发送事件的线程的封装类
final static class PostingThreadState {
//事件队列集合
final List<Object> eventQueue = new ArrayList<>();
boolean isPosting;
boolean isMainThread;
Subscription subscription;
Object event;
boolean canceled;
}
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));
}
}
}
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//订阅事件的集合
subscriptions = subscriptionsByEventType.get(eventClass);
}
//循环遍历
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {
postingState.event = event;
postingState.subscription = subscription;
boolean aborted = false;
try {
postToSubscription(subscription, event, postingState.isMainThread);
aborted = postingState.canceled;
} finally {
postingState.event = null;
postingState.subscription = null;
postingState.canceled = false;
}
if (aborted) {
break;
}
}
return true;
}
return false;
}
线程调度的三个post
private void checkPostStickyEventToSubscription(Subscription newSubscription, Object stickyEvent) {
if (stickyEvent != null) {
postToSubscription(newSubscription, stickyEvent, isMainThread());
}
}
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
//默认模式
case POSTING:
invokeSubscriber(subscription, event);
break;
case MAIN:
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
//HandlerPoster 放入队列
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
//不用区分是否在主线程
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
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);
}
}