【Android】EventBus详解
一,概述
EventBus即事件总线,在软件架构设计中,采用事件-发布-订阅类架构,通常具备高内聚低耦合特性,相对比通过Android#Broadcast方式,此框架由于不涉及跨进程方式,效率更加高效,并且提供了类似注解订阅方式,EventBus全局访问,不会被局限context组件。
笔者理解,这就是解耦框架,将不关联模块解耦,只通过总线方式通线,在企业级架构设计中,EventBus被经常使用。
二,实例
依赖
implementation "org.greenrobot:eventbus:3.3.1"
获取EventBus实例通常由默认方法getDefault,
或者通过build定制化参数获得,比如可以在build中添加SubscriberInfoIndex接口,自定义订阅方法,这就无需依赖Subscribe注解,
并且重写getSubscriberInfo方法即可
但笔者仍推荐Subscribe注解,但如果一个类中方法特别多,反射多方法存在性能开销,可以考虑index方式快速找到方法,
三,源码
1,register
1,通过subscriberFinder找到订阅方法,核心就在于怎么找,要么通过注解,要么通过index接口
2,对单个实例订阅该方法,订阅事件即方法参数
跟进findSubscribeMethods
1,从缓存查找,命中即返回
2,如果build参数ignoreGeneratedIndex为true,则直接通过反射查找,否则可以尝试index接口
3,index接口超找订阅方法
4,缓存
跟进findUsingInfo方法,
1,通过getSubscriberInfo找到SubscribeInfo,
2,如果没有index接口,则通过反射查找
跟进findUsingReflectionInSingleClass
1,反射所有声明方法
3,找到Subscribe注解方法
4,创建SubscribeMethod实体,保存此方法
最后,根据这个findState返回method
再将FindState放进对象池中,此处是享元模式设计,减少FindState创建数量
2,post
sticky粘性事件,sticky区分状态或事件,事件存在实时性,而状态存在唯一性,因此,状态一般是粘性,而事件则是非粘性,
在register中,通过订阅方法的sticky字段,决定是否将stickEvents中事件发布给订阅者,
stickyEvents需要显示添加,否则普通post仅是普通事件,无法加入stickyEvents Map
直接看post源码
1,从ThreadLocal中获得PostingThredState,其isPosing表示是否正在发送事件
当isPosing为false,则通过eventQueue出队消费事件,
跟进postSingleEvent
上述,存在可继承性事件判断,这在构造EventBus中设置,如下,
跟进postSingleEventForEventType
通过subscriptionEventType通过event快速获得订阅者,
这行map在register的subscribe中添加
跟进postToSubscription发布时间到subscription
根据线程模型,选择策略
POSTING:当前线程
MAIN:当前是主线程直接触发,或者加入主线程队列
MAIN_OROERED:加入主线程队列
BACKGROUND:子线程
ASYNC:反正异步,也是一个子线程
跟进invokeSubscribert
这就很简单了,method#invoke传入event即可,通知到订阅者
四,注意
避免内存泄漏,对于存在生命周期的对象,或需要销毁的对象,及时调用EventBus#unregister方法反注册,不然将作为Subscription#subscriber对象存在EventBus引用中。