1 EventBus简介
EventBus是由greenrobot组织贡献的一个Android事件发布/订阅轻量级框架。它的github地址是:
https://github.com/greenrobot/EventBus
看看github上面的简(吹)介(捧):
EventBus...
simplifies the communication between components
decouples event senders and receivers
performs well with Activities, Fragments, and background threads
avoids complex and error-prone dependencies and life cycle issues
makes your code simpler
is fast
is tiny (~60k jar)
is proven in practice by apps with 1,000,000,000+ installs
has advanced features like delivery threads, subscriber priorities, etc.
EventBus简化了应用程序内各个组件之间进行通信的复杂度,尤其是碎片之间进行通信的问题,可以避免由于使用广播通信而带来的诸多不便。而且它很快,包只有60k已经安装在了1,000,000,000+个应用中广泛使用了。
2 EventBus的简单使用
1 gradle中添加依赖
implementation 'org.greenrobot:eventbus:3.2.0'
2 添加混淆到混淆文件中。
*-keepattributes Annotation
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
如果你有用到AsyncExecutor类
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
}*
3 开始使用:
定义一个事件:
public class MessageEvent {
/* Additional fields if needed */
public String message;
public MessageEvent(String message) {
this.message = message;
}
}
准备订阅者的事件接收方法:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(this,event.message,Toast.LENGTH_LONG).show();
}
注册和解除订阅者的订阅事件:
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
发送事件:
findViewById(R.id.hello_eventBus).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EventBus.getDefault().post(new MessageEvent("this is an event"));
}
});
现在我们点击hello_eventBus这个控件,就是弹出Toast对话框。接下来一步步分析EventBus是如何实现这样的工作的:
先看一下EventBus.getDefault().register(this);这个方法;
3. EventBus的初始化
进入EventBus类中:
//使用单例模式构造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;
}
// 建造者模式
private static final EventBusBuilder DEFAULT_BUILDER = new EventBusBuilder();
public EventBus() {
this(DEFAULT_BUILDER);
}
//初始化EventBus内部的一些组件
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();
// 重点分析内容
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);
//异常打印器
logSubscriberExceptions = builder.logSubscriberExceptions;
//没有订阅者是否打印日志
logNoSubscriberMessages = builder.logNoSubscriberMessages;
// 是否发送异常处理 事件
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
//没有事件处理 是否发送 NoSubscriberEvent事件
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
//是否抛出异常
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
可以看到EventBus使用了单例模式创建,同时使用了构建者模式创建了一些必要的组件集合。
// key 为 Class 对象,value 为被订阅者的集合
private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
// key 为 Object 对象,value 为订阅者的集合
private final Map
上述几个集合先简单进行描述;
接下来先重点关注到几个相关的 Poster 是做什么?
MainThreadSupport
mainThreadSupport = builder.getMainThreadSupport();
// 获取looper
MainThreadSupport getMainThreadSupport() {
if (mainThreadSupport != null) {
return mainThreadSupport;
} else if (AndroidLogger.isAndroidLogAvailable()) {
Object looperOrNull = getAndroidMainLooperOrNull();
return looperOrNull == null ? null :
new MainThreadSupport.AndroidHandlerMainThreadSupport((Looper) looperOrNull);
} else {
return null;
}
}
static Object getAndroidMainLooperOrNull() {
try {
return Looper.getMainLooper();// 获取主线程的 Looper
} catch (RuntimeException e) {
// Not really a functional Android (e.g. "Stub!" maven dependencies)
return null;
}
}
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);
}
}
}
可以看到 MainThreadSupport 主要获取的是主线程的 Looper(通过 Looper.getMainLooper() 方法),AndroidHandlerMainThreadSupport 顾名思义,也是想要支持一些主线程将要进行的操作;
继续查看 createPoster 方法 创建了一个 HandlerPoster 的实例;
public class HandlerPoster extends Handler implements Poster {
private final PendingPostQueue queue; //PendingPostQueue 队列
private final int maxMillisInsideHandleMessage;
private final EventBus eventBus;
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) {
}
//处理消息
@Override
public void handleMessage(Message msg) {
}
HandlerPoster 类实现了 Handler 类,这里肯定和消息的处理有关,即实例中对应的 Toast 响应;
这里先对 enqueue 方法进行分析;
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");
}
}
}
}
了解 enqueue 方法之前,看来得先看看 PendingPost 是干嘛的;
PendingPost
final class PendingPost {
private final static List 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) {
synchronized (pendingPostPool) {
int size = pendingPostPool.size();
if (size > 0) {
PendingPost pendingPost = pendingPostPool.remove(size - 1);
pendingPost.event = event;
pendingPost.subscription = subscription;
pendingPost.next = null;
return pendingPost;
}
}
return new PendingPost(event, subscription);
}
// 重置 pendingPost 数据 加入到池子中
static void releasePendingPost(PendingPost pendingPost) {
pendingPost.event = null;
pendingPost.subscription = null;
pendingPost.next = null;
synchronized (pendingPostPool) {
// Don't let the pool grow indefinitely
if (pendingPostPool.size() < 10000) {
pendingPostPool.add(pendingPost);
}
}
}
}
可以看到 PendingPost 类维护了一个 PendingPost 的池子,每次调用 obtainPendingPost 其实就是组装一个 PendingPost 数据进行返回;
拿到了 PendingPost 之后,enqueue 方法会继续调用 queue.enqueue(pendingPost),这里就要继续查看 PendingPostQueue 类;
PendingPostQueue
final class PendingPostQueue {
private PendingPost head;
private PendingPost tail;
synchronized void enqueue(PendingPost pendingPost) { // 添加PendingPost
if (pendingPost == null) {
throw new NullPointerException("null cannot be enqueued");
}
if (tail != null) { // 添加到最后一位
tail.next = pendingPost;
tail = pendingPost;
} else if (head == null) {
head = tail = pendingPost;
} else {
throw new IllegalStateException("Head present, but no tail");
}
notifyAll();
}
synchronized PendingPost poll() {// 取 PendingPost
PendingPost pendingPost = head;
if (head != null) {
head = head.next;
if (head == null) {
tail = null;
}
}
return pendingPost;
}
synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException {//
if (head == null) {
wait(maxMillisToWait);
}
return poll();
}
}
PendingPostQueue 维护了一个 PendingPost 队列,用来添加以及取 PendingPost;PendingPost 添加完成了之后,调用 sendMessage 发送消息;
sendMessage 已经将消息发送出去,接下来继续看 HandlerPoster 的 handlerMessage 方法;
@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();// 取出 PendingPost
if (pendingPost == null) {
handlerActive = false;
return;
}
}
}
eventBus.invokeSubscriber(pendingPost); // 调用 invokeSubscriber 处理事件
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;
}
}
到这里,就可以发现了,其实 HandlerPoster 只是利用了 Handler ,当收到消息时候,组装PendingPost,并放入队列中,同时 Handler 发送一个消息,当 Handler 收到消息,则会从队列中取出 PendingPost ,然后最终通过 eventBus.invokeSubscriber(pendingPost) 调用处理事件;
到这里 MainThreadSupport 类介绍完毕,其中涉及到 HandlerPoster、PendingPost、PendingPostQuene 之间的相关操作,简单用以下示意图进行描述:
BackgroundPoster
接下来,继续查看 BackgroundPoster 类
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);// 开启线程池执行 run 方法;
}
}
}
// 从队列取出事件去执行
@Override
public void run() {
try {
try {
while (true) {
PendingPost pendingPost = queue.poll(1000);// 等待1000ms 去取PendingPost
if (pendingPost == null) {
synchronized (this) { // 保证同步性,所以下面再次调用 poll 方法确认
// 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;
}
}
}
BackgroundPoster 中 PendingPost 的构造过程与 HandlerPost 一致,与 MainThreadSupport 的 HandlerPoster 不同的是 ,BackgroundPoster 实现了 Runnale 方法;BackgroundPoster 对事件的分发调用处理应该是在 run 的方法中;
BackgroundPoster 构造完成了 PendingPost 后,通过线程池来执行 Runnale ,而 最后处理事件则是通过调用 EventBus 的 invokeSubscriber 方法;
所以 HandlerPoster 主要应用了 Handler 的机制在主线程处理,而 BackgroundPoster 则是直接在子线程取 PendingPost 进行 invokeSubscriber 调用处理;
同样,对 BackgroundPoster 进行示意图简单描述;
AsyncPoster
同理 asyncPoster = new AsyncPoster(this):
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);
}
}
AsyncPoster 和 BackgroundPoster 基本一致,区别在于 AsyncPoster 每次线程池只会取出一条 PendingPost 进行处理;
到这里 MainThreadSupport 中的 HandlerPoster 、BackgroundPoster、AsyncPoster 已经分析完成;
通过分析,以上三个 Poster 主要用于接收到消息信息后的 PendingPost 组装,区别在与主线程去处理消息则需要通过 Handler 机制,而对于子线程,直接开启线程在 run 方法进行处理即可;
接下来我们继续看下进行注解的方法:
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onMessageEvent(MessageEvent event) {
Toast.makeText(this,event.message,Toast.LENGTH_LONG).show();
}
View层进行注解
@Documented
@Retention(RetentionPolicy.RUNTIME) // 运行期间有效
@Target({ElementType.METHOD}) // 方法注解
public @interface Subscribe {
// 处理事件的所在线程
ThreadMode threadMode() default ThreadMode.POSTING;
// 是否是粘性事件,
boolean sticky() default false;
//时间的优先级
int priority() default 0;
}
Subscribe 注解方法定义了时间响应的线程、是否为粘性事件、以及事件的优先级。后面发送事件过程会继续进行详细分析;
几种处理事件的线程方式:
public enum ThreadMode {
POSTING, // 发送event事件的线程进行处理
MAIN, // 主线程处理,会阻塞 需要防止阻塞主线程
MAIN_ORDERED,// 主线程处理,不会在主线程阻塞
BACKGROUND, // 会在后台线程处理事件
ASYNC // 会创建一个新的线程处理
}
可以看到这里注解主要定义了运行区间以及处理事件的线程,这里的线程和之前分析的HandlerPoster、BackgroundPoster、AsyncPoster 对应;
4 register 注册事件订阅
EventBus.getDefault().register(this);
查看register()方法:
public void register(Object subscriber) {
Class> subscriberClass = subscriber.getClass(); // 获取注册所在的类
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);// 获取订阅的方法
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) { // 便利循环去订阅方法
subscribe(subscriber, subscriberMethod);// 绑定注册类以及订阅方法
}
}
}
register 方法会找到注册所在类(例如BaseActivity),通过 subscriberClass 找到所有的注册方法;通过subscribe 进行绑定;
查看 findSubscriberMethods 方法;
private static final Map
List findSubscriberMethods(Class> subscriberClass) {
List subscriberMethods = METHOD_CACHE.get(subscriberClass); // 通过缓存去取
if (subscriberMethods != null) {// 缓存拿到了数据即返回
return subscriberMethods;
}
if (ignoreGeneratedIndex) {// 默认为false
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;
}
}
如果缓存中有则去缓存中取出数据,如果没有,会通过 findUsingInfo 方法去查找类中的订阅方法,继续查看 findUsingInfo 方法:
private List findUsingInfo(Class> subscriberClass) {
FindState findState = prepareFindState(); // FindState 对象获取
findState.initForSubscriber(subscriberClass); // 赋值Class
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState); // 获取subscriberInfo
if (findState.subscriberInfo != null) {
SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods(); // 获取方法集合
for (SubscriberMethod subscriberMethod : array) {
if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) { // 检查方法
findState.subscriberMethods.add(subscriberMethod); // 添加方法到findState
}
}
} else { // 获取 SubscriberInfo
findUsingReflectionInSingleClass(findState);
}
findState.moveToSuperclass(); // 去父类查找
}
return getMethodsAndRelease(findState); // 释放相关资源
}
findUsingInfo 查找订阅方法主要通过 FindState 类进行操作;
FindState
查看 FindState 类
static class FindState {
final List subscriberMethods = new ArrayList<>(); // 订阅的方法集合
final Map anyMethodByEventType = new HashMap<>(); // EventType事件对应的方法的HashMap集合
final Map subscriberClassByMethodKey = new HashMap<>(); // methodKey对应的class的HashMap集合
final StringBuilder methodKeyBuilder = new StringBuilder(128);
Class> subscriberClass;// 注册方法所在的类 class
Class> clazz;
boolean skipSuperClasses;
SubscriberInfo subscriberInfo;
void initForSubscriber(Class> subscriberClass) {// 初始化 subscriberClass
this.subscriberClass = clazz = subscriberClass;
skipSuperClasses = false;
subscriberInfo = null;
}
FindState 主要保存了注册的类Class,以及相关订阅方法信息;
下图所示 FindState 和 SubscriberMethod 的关联;
继续往下查看 getSubscriberInfo 方法 ;
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) {
SubscriberInfo info = index.getSubscriberInfo(findState.clazz);
if (info != null) {
return info;
}
}
}
return null;
}
FindState 在初始化完成的时候并没有 SubscriberInfo 信息,实际这里执行了 findUsingReflectionInSingleClass 去获取的;
在这之前还是先看看 SubscriberInfo 类都有什么信息:
public interface SubscriberInfo {
Class> getSubscriberClass();
SubscriberMethod[] getSubscriberMethods();
SubscriberInfo getSuperSubscriberInfo();
boolean shouldCheckSuperclass();
}
是一个接口,那么后面肯定有实现 SubscriberInfo 的类,继续看 findUsingReflectionInSingleClass 方法;
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
// This is faster than getMethods, especially when subscribers are fat classes like Activities
methods = findState.clazz.getDeclaredMethods();// 获取注册类中的所有方法
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
try {
methods = findState.clazz.getMethods();// 获取注册类中的所有方法
} catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
String msg = "Could not inspect methods of " + findState.clazz.getName();
if (ignoreGeneratedIndex) {
msg += ". Please consider using EventBus annotation processor to avoid reflection.";
} else {
msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
}
throw new EventBusException(msg, error);
}
findState.skipSuperClasses = true;
}
for (Method method : methods) { // 遍历方法
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) { // public 方法
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();// 获取注解方法的线程声明
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));// 添加到 FindState 中,包含传参,处理事件的线程,优先级,是否是粘性事件
}
}
} 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");
}
}
}
findUsingReflectionInSingleClass 方法通过反射会找到注册类中所有的 subscribe 方法,然后将相关信息构造成 SubscriberMethod 类存到 FindState 的 subscriberMethods 中;
当前注册类 class 中执行完成后,会继续转移到注册类的父类中重复操作。找到父类中所有的订阅方法;直到没有父类了,最后将查找到的 subscriberMethods 返回,并释放 FindState 资源;
以上为默认 FindState.subscriberInfo 为空的情况的逻辑,实则当 subscriberInfo 不为空的情况下,有个 checkAdd 方法也会去查找父类,最终添加 subscriberMethod ;
拿到了所有的 subscriberMethods 方法,接下来则会调用到 subscribe(subscriber, subscriberMethod) 对获取的方法进行绑定:
private final Map, CopyOnWriteArrayList> subscriptionsByEventType;
private final Map
根据 类中注册的方法,subscribe 方法会根据 EventType 以及 subscriber 注册所在类进行分类;用 Map 结构进行保存数据;
粘性事件会通过 checkPostStickyEventToSubscription 方法马上进行发送;同时根据 eventInheritance 判断是否调用 EventType 对应的父类 以及 实现类的响应方法;
如下述方法中 A、B、C事件对应方法均会执行;
public class MainActivity extends Activity {
private static final String TAG="EventBus";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Log.v(TAG, "onStart()");
EventBus.getDefault().register(this);
EventBus.getDefault().post(new A());
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
Log.v(TAG, "onStop()");
}
public void onEvent(A msg){
Log.v(TAG, "onEvent(A msg)");
}
public void onEvent(B msg){
Log.v(TAG,"onEvent(B msg)");
}
public void onEvent(C msg){
Log.v(TAG,"onEvent(C msg)");
}
public void onEvent(D msg){
Log.v(TAG,"onEvent(D msg)");
}
}
到此,总结 EventBus.getDefalut().register(this) 方法主要做了以下工作:
1、创建HandlerPoster、BackgroundPoster、AsyncPoster去对应处理发送的消息;
2、获取注册类中的 subscriberMethod 方法,并且按照分类对应存储在 Map 中;
3、获取粘性事件,直接进行发送处理事件;
在上述 subscribe 方法中,粘性事件的处理方法 checkPostStickyEventToSubscription 还未进行查看,这里先放着,待后续分析发送事件后一起查看;
接下来继续看发送事件的方法
5 事件的返送
EventBus.getDefault().post(new MessageEvent("this is an event"));
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List
可以看到的是 eventQueue 维护了事件队列,并从 eventQueue 中取事件进行发送;
eventQueue 由 PostingThreadState 提供,查看 PostingThreadState 类;
PostingThreadState
final static class PostingThreadState {
final List
很简单,维护了一些基础数据;
查看 postSingleEvent 发送方法;
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class> eventClass = event.getClass();
boolean subscriptionFound = false;
if (eventInheritance) { // 事件父类对应的方法同时查找
List> 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));
}
}
}
lookupAllEventTypes 方法会查找到对应注册了 事件类的 父类的相关信息,同时进行发送;
postSingleEventForEventType 进行发送事件;
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class> eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized (this) {
subscriptions = subscriptionsByEventType.get(eventClass); // 按照事件分类的 集合;
}
if (subscriptions != null && !subscriptions.isEmpty()) {
for (Subscription subscription : subscriptions) {//遍历 集合
postingState.event = event;
postingState.subscription = subscription;
boolean aborted;
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;
}
Subscription 的结构如下;
final class Subscription {
final Object subscriber;
final SubscriberMethod subscriberMethod;
/**
* Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery
* {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions.
*/
volatile boolean active;
Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
active = true;
}
@Override
public boolean equals(Object other) {
if (other instanceof Subscription) {
Subscription otherSubscription = (Subscription) other;
return subscriber == otherSubscription.subscriber
&& subscriberMethod.equals(otherSubscription.subscriberMethod);
} else {
return false;
}
}
@Override
public int hashCode() {
return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
}
}
这里的 subscriptions 的获取就和之前 subscribe 绑定方法存储的信息关联上了,通过 subscriptions 可以找到,对应发送事件的 EventType 都在哪些类中进行注册了,同时获取到了注册方法的相关信息(也就是注解信息);
最后遍历集合,通过 postToSubscription 发送事件;
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 {
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);
}
}
以上根据实际发送事件所在线程,和我们定义的处理事件所在线程;进行不同的方法调用;
这里简单看下 MAIN ,即处理消息事件在主线程;
1 当我们的发送事件也是主线程的时候,调用 invokeSubscriber;
2 当我们的发送事件不是主线程,则要借用 Handler 进行处理了,这里就使用到了之前初始化的 mainThreadPoster;
实质上在 mainThreadPoster 的 HandlerPost 中,处理事件消息依然会调用到 invokeSubscriber,mainThreadPoster 只是作为消息机制的一个线程切换来使用;
其他的情况大同小异,可自行分析;
接下来,就查看 invokeSubscriber 方法了;对应的传参分别是:
1 subscription -- 包含注册事件所在类以及注册的方法;
2 event -- 事件本身;
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);
}
}
通过反射调用执行事件,完成整个发送-接收过程;
现在再回到之前没有继续查看的粘性事件中,有个 checkPostStickyEventToSubscription 方法,这里应该是直接调用执行粘性事件对应的绑定方法;我们查看源代码确认是否是这样的呢?
if (stickyEvent != null) {
// If the subscriber is trying to abort the event, it will fail (event is not tracked in posting state)
// --> Strange corner case, which we don't take care of here.
postToSubscription(newSubscription, stickyEvent, isMainThread());
}
可以看到这里调用了 postToSubscription ,和上述发送事件的方法一致,所以当我们对一个响应事件定义为粘性事件,实则相当于系统自动帮我们执行了发送事件方法。会直接调用响应事件中的处理;
到这里,EventBus的注册,到事件的处理整个基本流程就已经走完了;这里可以总结一下哪些重要步骤以及主要都是做了什么工作:
1 EventBus.getDefault(),创建响应 Poster ,对应 Poster 实则是为了处理线程的切换问题;
2 EventBus.getDefault().register();去查找项目中注解的方法,方法类型,方法名,注解所在类等集合数据,存储在本地并返回;
3 EventBus.getDefault().post(new MessageEvent("this is an event"));发送事件,对比对应本地存储的数据,同时依赖初始化建立的 Poster 切换线程;
4 粘性事件会在注册类初始化的时候立刻进行响应事件;
到这里EventBus的主要流程以及方法已经总结完了,可以看到EventBus主要用了java里面的反射方法以及Android中的handler处理机制,这里进行过多研究。
如果对handler有所疑惑;可查看探究Handler的运行机制.