如果你不知道事件总线是什么,那么没有关系,下面我们先来看这么一个场景:
你是否在开发的过程中遇到过想在activity-b中回调activity-a中的某个函数,但activity又不能手动创建对象来设置一个listener什么的? 你是否想在某个service中想更新activity或者fragment中的界面? 等等之类的组件之间的交互问题……
一经思考,你会发现android中的activity, fragment, service之间的交互是比较麻烦的,可能我们第一想到的是使用广播接收器来在它们之间进行交互。例如上述所说在activity-b中发一个广播,在activity-a中注册一个广播接收器来接受该广播。但使用广播接收器稍显麻烦,如果你要将一个实体类当做数据在组件之间传递,那么该实体类还得实现序列化接口,这个成本实在有点高啊!如下所示 :
是不是有很麻烦的感觉!
我们再来看一个示例,在开发过程中,我们经常要在子线程中做一些耗时操作,然后将结果更新到ui线程,除了asynctask之外,thread加handler是我们经常用的手段。我们看看如下示例:
是不是又有相当麻烦的感觉!!!
事件总线框架就是为了简化这些操作而出现的,并且降低组件之间的耦合而出现的,到底如何解决呢?咱们继续看下去吧。
androideventbus是一个android平台轻量级的事件总线框架, 它简化了activity、fragment、service等组件之间的交互,很大程度上降低了它们之间的耦合,使得我们的代码更加简洁,耦合性更低,提升我们的代码质量。
在往下看之前,你可以考虑这么一个场景,两个fragment之间的通信你会怎么实现?
如果你也这么觉得,那也就是你继续看下去的理由了。

androideventbus类似于观察者模式,通过register函数将需要订阅事件的对象注册到事件总线中,然后根据@subcriber注解来查找对象中的订阅方法,并且将这些订阅方法和订阅对象存储在map中。当用户在某个地方发布一个事件时,事件总线根据事件的参数类型和tag找到对应的订阅者对象,最后执行订阅者对象中的方法。这些订阅方法会执行在用户指定的线程模型中,比如mode=threadmode.async则表示该订阅方法执行在子线程中,更多细节请看下面的说明。
这个时候似乎它就没法处理了。而且规定死了函数命名,那就不能很好的体现该函数的功能,也就是函数的自文档性。androideventbus使用注解来标识接收函数,这样函数名不受限制,比如我可以把接收函数名写成updateuserinfo(person info),这样就灵活得多了。
另一个不同就是androideventbus增加了一个额外的tag来标识每个接收函数可接收的事件的tag,这类似于broadcast中的action,比如每个broadcast对应一个或者多个action,当你发广播时你得指定这个广播的action,然后对应的广播接收器才能收到.greenrobot的eventbus只是根据函数参数类型来标识这个函数是否可以接收某个事件,这样导致只要是参数类型相同,任何的事件它都可以接收到,这样的投递原则就很局限了。比如我有两个事件,一个添加用户的事件,
一个删除用户的事件,他们的参数类型都为user,那么greenrobot的eventbus大概是这样的:
如果你有两个同参数类型的接收函数,并且都要执行在主线程,那如何命名呢 ? 即使你有两个符合要求的函数吧,那么我实际上是添加用户的事件,但是由于eventbus只根据事件参数类型来判断接收函数,因此会导致两个函数都会被执行。androideventbus的策略是为每个事件添加一个tag,参数类型和tag共同标识一个事件的唯一性,这样就确保了事件的精确投递。
这就是androideventbus和greenrobot的eventbus的不同,但是由于本人对greenrobot的eventbus并不是很了解,很可能上述我所说的有误,如果是那样,欢迎您指出。
androideventbus起初只是为了学习,但是在学习了eventbus的实现之后,发现它在使用上有些不便之处,我想既然我有这些感觉,应该也是有同感之人,在开发群里交流之后,发现确实有这样的情况。因此才将正式地androideventbus以开源库的形式推出来,希望能够帮助到一些需要的人。当然,这个库的成长需要大家的支持与测试,欢迎大家发 pull request。
你可以按照下面几个步骤来使用androideventbus.
1 注册事件接收对象
2 通过subscriber注解来标识事件接收对象中的接收方法
接收函数使用tag来标识可接收的事件类型,与broadcastreceiver中指定action是一样的,这样可以精准的投递消息。mode可以指定目标函数执行在哪个线程,默认会执行在ui线程,方便用户更新ui。目标方法执行耗时操作时,可以设置mode为async,使之执行在子线程中。
3 在其他组件,例如activity, fragment,service中发布事件
发布事件之后,注册了该事件类型的对象就会接收到响应的事件.