EventBus使用及源码解析.docx
《EventBus使用及源码解析.docx》由会员分享,可在线阅读,更多相关《EventBus使用及源码解析.docx(21页珍藏版)》请在冰豆网上搜索。
EventBus使用及源码解析
EventBus使用及源码解析
1、前言
EventBus是由greenrobot开源的android事件订阅/发布轻量级框架,通过把事件发布者和接受者解耦进而简化android事件传递,其作用堪比android原有的handler、intent、broadcast,实现activity、fragment、service以及线程之间的通信;
1.1原理
1.2概述
2、EventBus
2.1使用
EventBus应用并通过demo实践:
分别用主线程发送数据和接送粘性数据进行了实践,其中有两种发送方式:
2.1.1主线程发送数据的使用步骤
(1)导jar包或添加依赖;
(2)注册广播;
(3)解注册广播;
(4)构建消息类;
(5)发送消息;
(6)接送消息;
2.1.2使用粘性事件
而使用粘性事件则可以先发送消息,接收消息时再进行注册;
(1)构造发送消息类;
(2)发送界面发送消息;
(3)目标界面实现接收消息的方法(添加@Subcruibe注解);
(4)注册广播;
(5)解注册(增加移除所有粘性事件的方法);
2.2源码解析
2.2.1获取实例
getDefault为一个单例方法,获取EventBus单例;
publicstaticEventBusgetDefault(){
if(defaultInstance==null){
synchronized(EventBus.class){
if(defaultInstance==null){
defaultInstance=newEventBus();
}
}
}
returndefaultInstance;
}
2.2.2NewEventBus
publicEventBus(){
this(DEFAULT_BUILDER);
}
在这里有调用了另外一个构造函数完成相关属性的初始化
EventBus(EventBusBuilderbuilder){
subscriptionsByEventType=newHashMap<>();
typesBySubscriber=newHashMap<>();
stickyEvents=newConcurrentHashMap<>();
mainThreadPoster=newHandlerPoster(this,Looper.getMainLooper(),10);
backgroundPoster=newBackgroundPoster(this);
asyncPoster=newAsyncPoster(this);
indexCount=builder.subscriberInfoIndexes!
=null?
builder.subscriberInfoIndexes.size():
0;
subscriberMethodFinder=newSubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification,builder.ignoreGeneratedIndex);
logSubscriberExceptions=builder.logSubscriberExceptions;
logNoSubscriberMessages=builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent=builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent=builder.sendNoSubscriberEvent;
throwSubscriberException=builder.throwSubscriberException;
eventInheritance=builder.eventInheritance;
executorService=builder.executorService;
}
DefaultBuilder就是一个默认的EventBusBuilder;
有了EventBus实例就可以进行注册了,
publicvoidregister(Objectsubscriber){
//得到当前注册类的class对象;
Class
>subscriberClass=subscriber.getClass();
//根据Class查找当前类中订阅事件方法的集合,即使用了@Subcribe注解,有public修饰符
、一个参数的方法;
//SubscriberMethod类主要封装了符合条件方法的相关信息
//Method对象、线程模式、事件类型、优先级、是否粘性事件等;
ListsubscriberMethods=subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized(this){
//循环遍历了订阅了事件的方法的集合,以完成注册
for(SubscriberMethodsubscriberMethod:
subscriberMethods){
subscribe(subscriber,subscriberMethod);
}
}
}
2.2.3Registe
register方法主要分成两部分:
查找和注册:
首先看查找部分的代码:
ListfindSubscriberMethods(Class
>subscriberClass){
//METHOD_CACHE是一个ConcurrentHashMap,直接保存了subscriberClass和对应SubscriberMethod的集合,以提高注册效率,赋值重复查找。
ListsubscriberMethods=METHOD_CACHE.get(subscriberClass);
if(subscriberMethods!
=null){
returnsubscriberMethods;
}
//由于使用了默认的EventBusBuilder,则ignoreGeneratedIndex属性默认为false,即是否忽略注解生成器
if(ignoreGeneratedIndex){
subscriberMethods=findUsingReflection(subscriberClass);
}else{
subscriberMethods=findUsingInfo(subscriberClass);
}
//如果对应类中没有符合条件的方法,则抛出异常
if(subscriberMethods.isEmpty()){
thrownewEventBusException("Subscriber"+subscriberClass
+"anditssuperclasseshavenopublicmethodswiththe@Subscribeannotation");
}else{
//保存查找到的订阅事件的方法
METHOD_CACHE.put(subscriberClass,subscriberMethods);
returnsubscriberMethods;
}
}
2.2.3.1FindSubscriberMethod
该方法很清晰,先从缓存中查找,如果找到直接返回,否则去做下一步的查找过程,然后缓存查找到的集合,FindUsingInfo方法会被调用。
privateListfindUsingInfo(Class
>subscriberClass){
FindStatefindState=prepareFindState();
findState.initForSubscriber(subscriberClass);
//初始状态下findState.clazz就是subscriberClass
while(findState.clazz!
=null){
findState.subscriberInfo=getSubscriberInfo(findState);
//条件不成立
if(findState.subscriberInfo!
=null){
SubscriberMethod[]array=findState.subscriberInfo.getSubscriberMethods();
for(SubscriberMethodsubscriberMethod:
array){
if(findState.checkAdd(subscriberMethod.method,subscriberMethod.eventType)){
findState.subscriberMethods.add(subscriberMethod);
}
}
}else{
//通过反射查找订阅事件的方法
findUsingReflectionInSingleClass(findState);
}
//修改findState.clazz为subscriberClass的父类Class,即需要遍历父类
findState.moveToSuperclass();
}
//查找到的方法保存在了FindState实例的subscriberMethods集合中。
//使用subscriberMethods构建一个新的List
//释放掉findState
returngetMethodsAndRelease(findState);
}
2.2.3.2FindUsingInfo
该方法会在当前类及父类查找订阅事件的方法,这里还引用了一个FindState静态内部类,用来辅助查找订阅事件的方法,具体的查找过程在findUsingReflectSingleClass()方法中,主要通过反射查找订阅事件;
privatevoidfindUsingReflectionInSingleClass(FindStatefindState){
Method[]methods;
try{
//ThisisfasterthangetMethods,especiallywhensubscribersarefatclasseslikeActivities
methods=findState.clazz.getDeclaredMethods();
}catch(Throwableth){
//Workaroundforjava.lang.NoClassDefFoundError,see
methods=findState.clazz.getMethods();
findState.skipSuperClasses=true;
}
//循环遍历当前类的方法,筛选出符合条件的
for(Methodmethod:
methods){
//获得方法的修饰符
intmodifiers=method.getModifiers();
//如果是public类型,但非abstract、static等
if((modifiers&Modifier.PUBLIC)!
=0&&(modifiers&MODIFIERS_IGNORE)==0){
//获得当前方法所有参数的类型
Class
>[]parameterTypes=method.getParameterTypes();
//如果当前方法只有一个参数
if(parameterTypes.length==1){
SubscribesubscribeAnnotation=method.getAnnotation(Subscribe.class);
//如果当前方法使用了Subscribe注解
if(subscribeAnnotation!
=null){
//得到该参数的类型
Class
>eventType=parameterTypes[0];
//checkAdd()方法用来判断FindState的anyMethodByEventTypemap是否已经添加过以当前
eventType为key的键值对,没添加过则返回true
if(findState.checkAdd(method,eventType)){
//得到Subscribe注解的threadMode属性值,即线程模式
ThreadModethreadMode=subscribeAnnotation.threadMode();
//创建一个SubscriberMethod对象,并添加到subscriberMethods集合
findState.subscriberMethods.add(newSubscriberMethod(method,eventType,threadMode,
subscribeAnnotation.priority(),subscribeAnnotation.sticky()));
}
}
}elseif(strictMethodVerification&&method.isAnnotationPresent(Subscribe.class)){
StringmethodName=method.getDeclaringClass().getName()+"."+method.getName();
thrownewEventBusException("@Subscribemethod"+methodName+
"musthaveexactly1parameterbuthas"+parameterTypes.length);
}
}elseif(strictMethodVerification&&method.isAnnotationPresent(Subscribe.class)){
StringmethodName=method.getDeclaringClass().getName()+"."+method.getName();
thrownewEventBusException(methodName+
"isaillegal@Subscribemethod:
mustbepublic,non-static,andnon-abstract");
}
}
}
到此register()方法中findSubscriberMethods()流程就分析完了,已经找到当前注册类及其父类订阅事件方法的集合,下面是具体的注册流程,即register的subscriber()方法。
2.2.3.3subscriber()方法
privatevoidsubscribe(Objectsubscriber,SubscriberMethodsubscriberMethod){
//得到当前订阅了事件的方法的参数类型
Class
>eventType=subscriberMethod.eventType;
//Subscription类保存了要注册的类对象以及当前的subscriberMethod
SubscriptionnewSubscription=newSubscription(subscriber,subscriberMethod);
//subscriptionsByEventType是一个HashMap,保存了以eventType为key,Subscription对象集合为value的键值对
//先查找subscriptionsByEventType是否存在以当前eventType为key的值
CopyOnWriteArrayListsubscriptions=subscriptionsByEventType.get(eventType);
if(subscriptions==null){
subscriptions=newCopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType,subscriptions);
}else{
if(subscriptions.contains(newSubscription)){
thrownewEventBusException("Subscriber"+subscriber.getClass()+"alreadyregisteredtoevent"
+eventType);
}
}
//添加上边创建的newSubscription对象到subscriptions中
intsize=subscriptions.size();
for(inti=0;i<=size;i++){
if(i==size||subscriberMethod.priority>subscriptions.get(i).subscriberMethod.priority){
subscriptions.add(i,newSubscription);
break;
}
}
//typesBySubscribere也是一个HashMap,保存了以当前要注册类的对象为key,
//注册类中订阅事件的方法的参数类型的集合为value的键值对
//查找是否存在对应的参数类型集合
List>>subscribedEvents=typesBySubscriber.get(subscriber);
if(subscribedEvents==null){
//不存在则创建一个subscribedEvents,并保存到typesBySubscriber
subscribedEvents=newArrayList<>();
typesBySubscriber.put(subscriber,subscribedEvents);
}
//保存当前订阅了事件的方法的参数类型
subscribedEvents.add(eventType);
if(subscriberMethod.sticky){
if(eventInheritance){
//ExistingstickyeventsofallsubclassesofeventTypehavetobeconsidered.
//Note:
Iteratingoveralleventsmaybeinefficientwithlotsofstickyevents,
//thusdatastructureshouldbechangedtoallowamoreefficientlookup
//(e.g.anadditionalmapstoringsubclassesofsuperclasses:
Class->List).
Set>,Object>>entries=stickyEvents.entrySet();
for(Map.Entry>,Object>entry:
entries){
Class
>candidateEventType=entry.getKey();
if(eventType.isAssignableFrom(candidateEventType)){
ObjectstickyEvent=entry.getValue();
checkPostStickyEventToSubscription(newSubscription,stickyEvent);
}
}
}else{
ObjectstickyEvent=stickyEvents.get(eventType);
checkPostStickyEventToSubscription(newSubscription,stickyEvent);
}
}
}
Subscriber()方法主要是为了得到subscriptionsByEventType、TypesBySubscriber两个HashMap,在发送事件时要用到subscriptionsByEventType,完成时间的处理,当取消EventBus注册时则要用到TypesBySubscriber、subscriptionsByEventType完成相关资源的释放;
下面是取消注册:
EventBus.getDefault.unRegister(this),其核心的方法就是unsubscriberByEventType();
publicsynchronizedvoidunregister(Objectsubscriber){
//得到当前注册类对象对应的订阅事件方法的参数类型的集合
List>>subscribedTypes=typesBySubscriber.get(subscriber);
if(subscribedTypes!
=null){
//遍历参数类型集合,释放之前缓存的当前类中的Subscription
for(Class
>eventType:
subscribedTypes){
unsubscribeByEventType(subscriber,eventType);
}
//删除以subscriber为key的键值对
typesBySubscriber.remove(subscriber);
}else{
Log.w(TAG,"Subscribertounregisterwasnotregisteredbefore:
"+subscriber.getClass());
}
}
然后再看下unsubscribe