EventBus使用及源码解析.docx

上传人:b****7 文档编号:8964300 上传时间:2023-02-02 格式:DOCX 页数:21 大小:350.09KB
下载 相关 举报
EventBus使用及源码解析.docx_第1页
第1页 / 共21页
EventBus使用及源码解析.docx_第2页
第2页 / 共21页
EventBus使用及源码解析.docx_第3页
第3页 / 共21页
EventBus使用及源码解析.docx_第4页
第4页 / 共21页
EventBus使用及源码解析.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

EventBus使用及源码解析.docx

《EventBus使用及源码解析.docx》由会员分享,可在线阅读,更多相关《EventBus使用及源码解析.docx(21页珍藏版)》请在冰豆网上搜索。

EventBus使用及源码解析.docx

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 交通运输

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1