开始
- EventBus的基本用法, 下面代码通过EventBus在两个Activity传递数据(当然也可以使用其他方法传递数据)这里只是作为演示用
public class FirstActivity extends BaseActivity {
private TextView mTv;
private static final String TAG = "FirstActivity";
@Override
protected void initView() {
setContentView(R.layout.activity_first);
mTv = findViewById(R.id.tv);
}
/**
* 必须要是public、void并且有且只有一个参数,粘性表示当一个粘性消息已经发送了再注册还能再接受到该消息
* @param msg 接受到的消息对象,可以任意
*/
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onReceiveEvent(Message msg) {
Log.d(TAG, "onReceiveEvent: currentThread is " + Thread.currentThread());
mTv.setText((String)msg.obj);
}
public void subscribe(View view) {
EventBus.getDefault().register(this);
}
public void unSubscribe(View view) {
EventBus.getDefault().unregister(this);
}
public void jump(View view) {
startActivity(new Intent(this, SecondActivity.class));
}
}
public class SecondActivity extends BaseActivity {
@Override
protected void initView() {
setContentView(R.layout.activity_second);
}
public void sendStickyMsg(View view) {
Message msg = Message.obtain();
msg.obj = "我是第二个Activity通过发送消息带回来的数据";
EventBus.getDefault().post(msg);
}
public void sendMsg(View view) {
Message msg = Message.obtain();
msg.obj = "我是第二个Activity通过发送粘性消息带回来的数据";
EventBus.getDefault().postSticky(msg);
}
}
源码分析
1. 从EventBus.getDefault()说起,这是一个典型的DLC单例模式(也可以使用builder创建一个EventBus实例)
// EventBus.java
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
// 接着看看构造方法
public EventBus() {
this(DEFAULT_BUILDER);
}
EventBus(EventBusBuilder builder) {
logger = builder.getLogger(); // 1
// key是事件类型,value是List<Subscription>
subscriptionsByEventType = new HashMap<>();
// key是订阅者,List<事件类型>,该对象存在的目的便于解除注册时删除
typesBySubscriber = new HashMap<>();
// 保存着所有的粘性事件
stickyEvents = new ConcurrentHashMap<>();
mainThreadSupport = builder.getMainThreadSupport(); // 2
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null; // 后面用到会说
backgroundPoster = new BackgroundPoster(this); // 后面用到会说
asyncPoster = new AsyncPoster(this); // 后面用到会说
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0; // 索引的数量,如果有索引的话
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex); // 3
logSubscriberExceptions = builder.logSubscriberExceptions; // true
logNoSubscriberMessages = builder.logNoSubscriberMessages; // true
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent; // true
sendNoSubscriberEvent = builder.sendNoSubscriberEvent; // true
throwSubscriberException = builder.throwSubscriberException; // false
eventInheritance = builder.eventInheritance; // true 是否允许事件继承
executorService = builder.executorService; // Executors.newCachedThreadPool()
}
关于索引,我们可以调用EventBusBuilder.addIndex添加索引,不使用Subscribe注解手动把订阅方法通过SubscriberInfoIndex.getSubscriberInfo进行返回 可以看看这篇博客
关于事件继承,比如通过Post发送了一个事件对象ArrayList如果开启了事件继承那么方法参数为Object、Collection、List、ArrayList等(只要能够上转型)都能够接受到该事件,如果没开启那么只有方法参数是ArrayList才能够接受到事件
注释1. 创建了一个Logger对象内部判断如果有自定义Logger就是用自定义的,否则判断是否有Log类和能否拿到主线程的Looper,如果能拿到就是用Log进行打印不然通过System.out进行打印
// EventBusBuilder.java
Logger getLogger() {
// 如果有自定义logger就使用自定义的
if (logger != null) {
return logger;
} else {
// 判断是否有Log类,并且能不能拿到主线程的Looper,如果可以使用AndroidLogger否则使用Logger.SystemOutLogger
return Logger.AndroidLogger.isAndroidLogAvailable() && getAndroidMainLooperOrNull() != null
? new Logger.AndroidLogger("EventBus") :
new Logger.SystemOutLogger();
}
}
注释2. 如果是Android那么创建一个AndroidHandlerMainThreadSupport否则返回null
// EventBusBuilder.java
MainThreadSupport getMainThreadSupport() {
if (mainThreadSupport != null) {
return mainThreadSupport;
} else if (Logger.AndroidLogger.isAndroidLogAvailable()) {
Object looperOrNull = getAndroidMainLooperOrNull();
return looperOrNull == null ? null :
new MainThreadSupport.AndroidHandlerMainThreadSupport((Looper) looperOrNull);
} else {
return null;
}
}
// MainThreadSupport$AndroidHandlerMainThreadSupport.class
public interface MainThreadSupport {
boolean isMainThread();
Poster createPoster(EventBus eventBus);
class AndroidHandlerMainThreadSupport implements MainThreadSupport {
private final Looper looper;
public AndroidHandlerMainThreadSupport(Looper looper) {
this.looper = looper;
}
@Override
public boolean isMainThread() {
return looper == Looper.myLooper();
}
@Override
public Poster createPoster(EventBus eventBus) {
return new HandlerPoster(eventBus, looper, 10);
}
}
}
重点来看看注释7 SubscriberMethodFinder
SubscriberMethodFinder(List<SubscriberInfoIndex> subscriberInfoIndexes, boolean strictMethodVerification,
boolean ignoreGeneratedIndex) {
// null, false, false
this.subscriberInfoIndexes = subscriberInfoIndexes;
this.strictMethodVerification = strictMethodVerification;
this.ignoreGeneratedIndex = ignoreGeneratedIndex;
}
// 看看findSubscriberMethods
List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {
// 首先从缓存中取,如果能取到就直接返回了
List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);
if (subscriberMethods != null) {
return subscriberMethods;
}
// 默认ignoreGeneratedIndex为false,表示是否忽略APT生成的索引
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;
}
}
// ignoreGeneratedIndex默认为false,接着看findUsingInfo
private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {
// 从池中取出一个FindState,如果不存在就新建一个
FindState findState = prepareFindState();
// 初始化subscriberClass、skipSuperClasses
findState.initForSubscriber(subscriberClass);
// 遍历订阅者的Class及其SuperClass(如果需要的话),找出所有被Subscribe注解的、公开的、参数是一个的方法
while (findState.clazz != null) {
// 如果有调用addIndex那么会回调getSubscriberInfo
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 {
// 通过反射去查找一个类中所有被Subscribe注解的方法
findUsingReflectionInSingleClass(findState);
}
// 移动到父类如果是java、android等系统库返回null,避免影响性能,因为里面肯定没有Subscribe注解
findState.moveToSuperclass();
}
return getMethodsAndRelease(findState);
}
private SubscriberInfo getSubscriberInfo(FindState findState) {
if (findState.subscriberInfo != null && findState.subscriberInfo.getSuperSubscriberInfo() != null) {
SubscriberInfo superclassInfo = findState.subscriberInfo.getSuperSubscriberInfo();
if (findState.clazz == superclassInfo.getSubscriberClass()) {
return superclassInfo;
}
}
if (subscriberInfoIndexes != null) {
for (SubscriberInfoIndex index : subscriberInfoIndexes) {
// 如果有调用addIndex那么会回调getSubscriberInfo
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// 这个方法被getMethods快尤其是对于代码很多的类比如Activity
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// 好像是由于混淆的原因getDeclaredMethods可能会失败,就改成getMethod
methods = findState.clazz.getMethods();
// 既然通过getMethods获取方法了,那么就可以跳过父类了
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
// 如果不是public或者是Abstract、Static那么返回false
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class<?>[] parameterTypes = method.getParameterTypes();
// 如果不是一个参数,那么也同样的忽略或者抛出异常
if (parameterTypes.length == 1) {
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) {
Class<?> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
ThreadMode threadMode = subscribeAnnotation.threadMode();
// 封装成一个SubscriberMethod保存进subscriberMethods中
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");
}
}
}
2. 订阅 EventBus.register(Object subscriber)
上文已经讲了调用findSubscriberMethods会将当前class以及其superClass中的所有被Subscribe注解修饰的公开的非abstract、final参数是一个的方法封装成一个SubscriberMethod对象保存在FindState.subscriberMethods中,所以接下来着重看看subscribe方法
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
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);
// 获取该事件的所有订阅者信息
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);
}
}
// 根据优先级放入对应的位置,subscriptions按照优先级从大到小排列
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);
}
}
}
3. EventBus.getDefault().post(Object)、postSticky后者与前者的区别只是会将事件放入StickyEvent列表中
public void post(Object event) {
// 获取当前线程的PostingThreadState
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
// 这个判断isPosting主要是为了防止内部调用postSingleEvent,然后没找到对应的订阅方法会再调用post(NoSubscriberEvent)
// 可以通过订阅参数为NoSubscriberEvent的方法,来检测没有找到对应的订阅方法的请求
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;
}
}
}
// 如果没有找到会再post一个NoSubscriberEvent因此该方法会被调用,可以获取originalEvent拿到原始的事件
@Subscribe(threadMode = ThreadMode.MAIN)
public void onReceiveNoSubscriberEvent(NoSubscriberEvent event) {
Log.d(TAG, event.originalEvent.toString());
}
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);
// 分发事件,如果找到对应的接受者,返回true,否则返回false
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) {
// 没有找到订阅那么就发送一个NoSubscriberEvent
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;
}
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:
// 当前线程直接执行
invokeSubscriber(subscription, event);
break;
case MAIN:
// 如果当前线程是主线程那么直接运行,不然的话放到mainThreadPoster也就是HandlerPoster实例中
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
break;
case MAIN_ORDERED:
// Android中始终放入到mainThreadPoster中运行
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(subscription, event);
}
break;
case BACKGROUND:
// 如果当前线程是主线程那么放入backgroundPoster中,否则就直接运行
if (isMainThread) {
backgroundPoster.enqueue(subscription, event);
} else {
invokeSubscriber(subscription, event);
}
break;
case ASYNC:
// 放入asyncPoster中
asyncPoster.enqueue(subscription, event);
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);
}
}
// invokeSubscriber,直接就是反射调用方法
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);
}
}
// mainThreadPoster.enqueue这里的mainThreadPoster其实就是HandlerPoster对象
public void enqueue(Subscription subscription, Object event) {
// 内部维护了一个PendingPost数组,如果有空余的那么就获取返回,否则新建一个
PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event);
synchronized (this) {
queue.enqueue(pendingPost);
if (!handlerActive) {
handlerActive = true;
// 发送一个消息启动handleMessage里面的循环
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) {
// 不断的从队列中取直到队列为空或者时间超过了maxMillisInsideHandleMessage
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;
}
}
// backgroundPoster
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) {
// 如果1秒内取不到PendPost就退出循环
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;
}
}
// AsyncPoster
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 = queue.poll();
if(pendingPost == null) {
throw new IllegalStateException("No pending post available");
}
eventBus.invokeSubscriber(pendingPost);
}
}
4. EventBus.getDefault().unregister()
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());
}
}
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
// 如果发现是指定的订阅者那么就移除
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}