简单使用
- 注册
EventBus.getDefault().register(this);
- 声明方法(post发送事件的时候,反射调用),不能是private 类型的方法,否则在编译的时候会报错.可以在@Subscribe(threadMode = ThreadMode.MAIN)指定接收事件的时候运行的线程.如果不写,默认是ThreadMode.POSTING
@Subscribe
public void busMethod(String s){
Log.d(TAG, "busMethod: " + s);
}
@Subscribe(threadMode = ThreadMode.MAIN)
protected void busMethod(Object obj){
}
- 发送事件,可以传递任何数据类型,对象需要序列化
EventBus.getDefault().post("test obj");
- 注销注册
EventBus.getDefault().unregister(this);
四种threadMode
1. ThreadMode.POSTING
post发送事件是在什么线程,接收就在什么线程
2. ThreadMode.MAIN
post发送事件不管在什么线程,接收肯定在主线程(UI线程)
3. ThreadMode.BACKGROUND
post发送事件不管在什么线程,接收肯定在子线程
4. ThreadMode.ASYNC
post不管在什么线程,都会创建新的子线程来接收.
EventBus.getDefault()源码
EventBus(EventBusBuilder builder) {
//以订阅方法参数类型为key,订阅的类和方法的封装为value
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();//记录订阅的对象,和方法的参数类型
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);//主线程Handler
backgroundPoster = new BackgroundPoster(this);//子线程Handler
asyncPoster = new AsyncPoster(this);//处理ThreadMode.ASYNC的Handler
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;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance; //默认是 true
executorService = builder.executorService;//线程池
}
EventBus.getDefault的时候是进行了一些数据的初始化
register源码
public void register(Object subscriber) {
Class> subscriberClass = subscriber.getClass();
List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
通过findSubscriberMethods方法,找到注册类中用来接收消息的方法,
findSubscriberMethods
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;
}
}
这里有用Map
Map集合把该类的接收事件方法缓存,避免下次重复处理,ignoreGeneratedIndex 默认是false,进入findUsingInfo方法
findUsingInfo
private List findUsingInfo(Class> subscriberClass) {
FindState findState = prepareFindState();//创建FindState 来记录方法的一些信息
findState.initForSubscriber(subscriberClass);
while (findState.clazz != null) {
findState.subscriberInfo = getSubscriberInfo(findState);
if (findState.subscriberInfo != null) { //默认是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);
}
findState.subscriberInfo默认是null,所以就走到findUsingReflectionInSingleClass()方法
findUsingReflectionInSingleClass
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
methods = findState.clazz.getDeclaredMethods();//获取该类所有的方法
} catch (Throwable th) {
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;
}
for (Method method : methods) {
int modifiers = method.getModifiers();
if ((modifiers & Modifier.PUBLIC) != 0 && (modifiers & MODIFIERS_IGNORE) == 0) {
Class>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length == 1) { //只有一个参数才满足
//获取方法上面的@Subscribe注释
Subscribe subscribeAnnotation = method.getAnnotation(Subscribe.class);
if (subscribeAnnotation != null) { //@Subscribe注释不为 null 才满足
Class> eventType = parameterTypes[0];
if (findState.checkAdd(method, eventType)) {
//获取接收事件方法的 threadMode 类型
ThreadMode threadMode = subscribeAnnotation.threadMode();
//把方法名,参数类型, threadMode类型都封装到SubscriberMethod对象,用findState来管理
findState.subscriberMethods.add(new SubscriberMethod(method, eventType, threadMode,
subscribeAnnotation.priority(), subscribeAnnotation.sticky()));
}
}
...
}
这里就是找到注册类中具体的方法,进行一些封装并且记录起来,然后结束这个方法,进入到return getMethodsAndRelease(findState);最后一个方法,返回一个List
private List getMethodsAndRelease(FindState findState) {
List subscriberMethods = new ArrayList<>(findState.subscriberMethods);
findState.recycle();
synchronized (FIND_STATE_POOL) {
for (int i = 0; i < POOL_SIZE; i++) {
if (FIND_STATE_POOL[i] == null) {
FIND_STATE_POOL[i] = findState;
break;
}
}
}
return subscriberMethods;
}
getMethodsAndRelease() 方法就是清空findState对象里面的一些数据,释放内存,并且这里使用了FindState[] FIND_STATE_POOL ,FindState[] 数组来循环利用,避免销毁更多的内存
得到这些接收事件的方法之后,遍历这个保存事件方法的List集合,进行subscribe()订阅.
subscribe源码
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class> eventType = subscriberMethod.eventType;//记录订阅方法的参数类型
//newSubscription 记录订阅类和方法
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
//以订阅方法参数类型为key,CopyOnWriteArrayList为value
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> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
//订阅的类为 key ,ArrayList 为value
typesBySubscriber.put(subscriber, subscribedEvents);
}
//记录参数类型
subscribedEvents.add(eventType);
...
//sticky粘性事件的一些处理
}
具体的订阅就是用Map
post源码
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List
把post要传递的对象添加eventQueue这个List集合队列里面,然后到while 里面循环遍历,调用postSingleEvent发送事件消息,postSingleEvent方法会调用postSingleEventForEventType方法来完成.
postSingleEventForEventType
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class> eventClass) {
CopyOnWriteArrayList subscriptions;
synchronized (this) {
//这里就根据 post要传递的参数类型,获取到对应的类和方法的信息
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;
}
可以看到,这里是根据要传递的参数类型(EventBus.getDefault().post(传递参数)),来获取到上面订阅的时候保存的类和方法的信息,然后遍历,调用postToSubscription方法,去发送事件消息
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 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);
}
}
判断订阅方法的threadMode模式,利用不同线程的Handler进行线程切换,做不同的处理.最后都是调用invokeSubscriber方法通过反射调用到接收事件通知的方法来完成事件的通知过程..
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);
}
}
unregister注销注册源码
//订阅的类为 key ,接收事件方法的参数类型的List集合 为value
//typesBySubscriber.put(subscriber, subscribedEvents);
public synchronized void unregister(Object subscriber) {
//typesBySubscriber订阅事件的时候,保存的信息
List> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class> eventType : subscribedTypes) {
unsubscribeByEventType(subscriber, eventType);//遍历删除
}
typesBySubscriber.remove(subscriber);//从Map集合里面删除
} else {
Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
注销注册就是从对应的Map集合里面把对应的订阅者类,删除掉.
unsubscribeByEventType
private void unsubscribeByEventType(Object subscriber, Class> eventType) {
//根据参数类型,获取到对应的订阅者类的集合
List 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--;
}
}
}
}