EventBus是用于数据传输的开源第三方库,可以深度的解耦合,代码的间接性也更好,目前最新版本是EventBus3.0,我们分析的是这个版本,首先看下这个库的使用,以在Activity为例:
public class MainActivity{
protected onCreate(){
EventBus.getDefault().register(this);
}
@Subscrible(threadMode=ThreadMode.BACKGROUND,sticky=true,priority=100)
public void getData(String data){
//方法名随便定义,
}
protected onDestory(){
EventBus.getDefault().unRegister(this);
}
}
public class FirstActivity{
protected void onCreate(){
EventBus.getDefault().post("哈哈哈");
//或者
EventBus.getDefault().postSticky("嘻嘻嘻");
}
}
现在分析源码:
使用单例模式创建EventBus对象
private static volatile EventBus defaultInstance;
使用Builder模式扩展可选参数,构建eventBus对象,DEFAULT_BUILDER是一个默认的EventBusBuilder对象,
eventbus里面的参数全都可以自己配置,配置完成后调用build()方法,返回EventBus对象
然后看register方法
subscriberClass是注册的类对象,根据这个类查找所有被subscriber注解的方法,返回一个list集合中,然后遍历每一个被注解的方法。
METHOD_CACHE是一个线程安全的Map,key是类,value是注解集合,如果之前有存储,直接取出并返回,ignoreGeneragtedIndex是是否忽略反射查找subscriber注解的方法,默认是false,因为在编译期会自动生成注解过的方法(在build/generate/apt…中,可惜我没找到),提高性能,如果注册的类中没有注解的方法,则会抛出异常,查找完成后保存到Map中,findUsingReflection(subscriberClass)反射查找方法,
prepareFindState()是从findState数组中取出一个findstate对象,然后初始化findState,whie循环遍历该类和其父类的方法,如果父类是framework层或者java层的跳出循环,
然后存储完之后看getMethodsAndRealease()方法
将findState保存的注解对象倒出来,自己recycle,将这个对象又还给数值池中,设计的很精妙啊!再看下通过索引获取methods集合–findUsingInfo()方法。
现在回到register方法,看subscriber(subscriber,subscriberMethod)方法
sticky设置为true,则在注册的时候,就开始执行postSticky方法,该方法是将发布对象存储在stickyEvents中,属于先发布事件,在注册订阅时执行方法,比如从Activity A–>Activity B,在A中post,在B中注册,用postSticky方法,类似于onActivityResult方法。
在看发布事件 post方法
currentPostingThreadState是个ThreadLocal,它可以保持单个线程数据的独立性,
发送单个事件
backgroundPoster和asyncPoster都是继承Runnable,然后交给Exectuctor.execute(this)执行,这些方法最后总都是执行invokeSubscriber()方法
最后看下unRegister解绑过程
总结:register会把所有注解的方法保存在一个Map中,post方法会由订阅类型到map中查找对应该类型的方法,反射调用。