ASYNC 所有消息都会抛到一个独立的线程处理。适合耗时操作。执行线程从线程池中获取。EventBus会采用线程池,动态的扩展线程。默认采用的线程池是newCachedThreadPool. 避免同时提交过多的耗时操作,导致线程池创建过多的线程。 Avoid triggering a large number of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads
/**
* Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus.
* EventBus takes care of threading independently from the posting thread.
*
* @see EventBus#register(Object)
* @author Markus
*/publicenumThreadMode{/**
* Subscriber will be called directly in the same thread, which is posting the event. This is the default. Event delivery
* implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for
* simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers
* using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
*/
POSTING,/**
* On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is
* the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event
* is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread.
* If not on Android, behaves the same as {@link #POSTING}.
*/
MAIN,/**
* On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN},
* the event will always be queued for delivery. This ensures that the post call is non-blocking.
*/
MAIN_ORDERED,/**
* On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods
* will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single
* background thread, that will deliver all its events sequentially. Subscribers using this mode should try to
* return quickly to avoid blocking the background thread. If not on Android, always uses a background thread.
*/
BACKGROUND,/**
* Subscriber will be called in a separate thread. This is always independent from the posting thread and the
* main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should
* use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number
* of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus
* uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.
*/
ASYNC
}
/**
* Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they
* are no longer interested in receiving events.
* <p/>
* Subscribers have event handling methods that must be annotated by {@link Subscribe}.
* The {@link Subscribe} annotation also allows configuration like {@link
* ThreadMode} and priority.
*/publicvoidregister(Object subscriber){Class<?> subscriberClass = subscriber.getClass();// 解析类的所有方法,找到有注解的方法List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);synchronized(this){for(SubscriberMethod subscriberMethod : subscriberMethods){subscribe(subscriber, subscriberMethod);//将解析的方法,添加到map数据结构中去}}}
findSubscriberMethods,解析@Subscribe解方法
入参是register注册函数传入的subscriber的class对象类型。
如果找不到注解函数,会抛出异常。
List<SubscriberMethod>findSubscriberMethods(Class<?> subscriberClass){List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);//查缓存if(subscriberMethods !=null){return subscriberMethods;}if(ignoreGeneratedIndex){// 是否忽略通过预编译生成的Index查找Method额方式,默认值false
subscriberMethods =findUsingReflection(subscriberClass);//直接通过反射查找类}else{
subscriberMethods =findUsingInfo(subscriberClass);// 查找注解方法}if(subscriberMethods.isEmpty()){thrownewEventBusException("Subscriber "+ subscriberClass
+" and its super classes have no public methods with the @Subscribe annotation");}else{
METHOD_CACHE.put(subscriberClass, subscriberMethods);return subscriberMethods;}}
/** Posts the given event to the event bus. */publicvoidpost(Object event){PostingThreadState postingState = currentPostingThreadState.get();// ThreadLocal对象初始化List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);//post的事件添加到队列中if(!postingState.isPosting){// 如果当前正在对外发送消息。
postingState.isMainThread =isMainThread();
postingState.isPosting =true;if(postingState.canceled){thrownewEventBusException("Internal error. Abort state was not reset");}try{while(!eventQueue.isEmpty()){postSingleEvent(eventQueue.remove(0), postingState);}}finally{
postingState.isPosting =false;
postingState.isMainThread =false;}}}
/**
* Invokes the subscriber if the subscriptions is still active. Skipping subscriptions prevents race conditions
* between {@link #unregister(Object)} and event delivery. Otherwise the event might be delivered after the
* subscriber unregistered. This is particularly important for main thread delivery and registrations bound to the
* live cycle of an Activity or Fragment.
*/voidinvokeSubscriber(PendingPost pendingPost){Object event = pendingPost.event;Subscription subscription = pendingPost.subscription;PendingPost.releasePendingPost(pendingPost);if(subscription.active){invokeSubscriber(subscription, event);}}voidinvokeSubscriber(Subscription subscription,Object event){try{
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);// 通过反射调用函数接口}catch(InvocationTargetException e){handleSubscriberException(subscription, event, e.getCause());}catch(IllegalAccessException e){thrownewIllegalStateException("Unexpected exception", e);}}
// Build the project at least once to generate the index class specified with eventBusIndex.// Then, e.g. in your Application class, use EventBus.builder().addIndex(indexInstance) to pass an instance of the index class to EventBus.EventBus eventBus =EventBus.builder().addIndex(newMyEventBusIndex()).build();
// Use EventBusBuilder.installDefaultEventBus() to set the EventBus with index as the instance returned by EventBus.getDefault().EventBus.builder().addIndex(newMyEventBusIndex()).installDefaultEventBus();// Now the default instance uses the given index. Use it like this:EventBus eventBus =EventBus.getDefault();