微信号:androidwalker

介绍:关注Android新技术、进阶开发

开源组件:EventBus

2016-06-06 07:26 xjj_app


        工欲善其事,必先利其器。我们做代码开发,最希望的就是不要重复造轮子。而是利用现成的工具来辅助我们开发,既可以学习和借鉴别人优秀的代码,又能提高开发效率,何乐而不为呢?



1简介


        今天我们就推荐一款在github非常受欢迎的开源组件——EventBus。从字面上理解,既有Event(事件),又有Bus(总线,不是巴士哈),所以,想想这个组件应该是起事件分发枢纽作用的。

         先来看一下,这个组件有多火,在github搜索“EventBus”,可以看到有9千多人加新,近3千的forks啊。



2优点

    

        使用EventBus的好处是什么呢?  这里有作者关于EventBus的简介(经过翻译,翻译不好见谅):经过优化的Android事件总线,可以简化Activity、Fragment、线程、服务等之间的通信,开发者可以编写更少的代码就可以获得高质量的程序。  

        更加系统性的总结如下:

  • 简化程序之间的事件传递

  • 使你的代码看起来更加简洁

  • 运行效率高

  • jar包很小,才50k左右

  • 1亿+的安装量

  • 可以避免复杂的依赖关系和生命周期问题


3接入三部曲


  • 自定义事件

    public class MessageEvent { /* Additional fields if needed */ }

    EventBus的事件可以是任何的对象,也就是说任何的类都可以作为EventBus的事件来传递。我们可以自定义一个类,然后在类里面声明需要传递的参数变量,在对这些变量赋值,传递给接收者。


  • 注册事件接收者,声明回调方法

    通过register来注册事件接收者

    eventBus.register(this);

    同时,还需要在接收者里面定义回调方法,我们可以在回调里面处理接收到的事件。AnyEventType就是第一步提到的MessageEvent对象

    @Subscribe
    public void onEvent(AnyEventType event) {/* Do something */};


  • 发送事件

    最后,需要发送事件的发送者,可以通过如下代码将事件发送出去

    eventBus.post(event);



4事件分类


        在EventBus对事件的回调做了分类,主要有onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync。这些回调方法都是保留的,开发者可以直接在Subcriber里面定义。

        

1

onEvent

    

        如果Subcriber定义了onEvent这个回调方法,则Publisher在哪一个线程发出的事件,则onEvent就在哪一个线程执行。也即,Subcriber和Publisher在同一个线程。


        

2

onEventMainThread


        由于上述onEvent可以满足基本需求,但android的UI是不能在子线程操作的,所以,EventBus定义了onEventMainThread。即使Publisher在子线程的发出的事件,Subscriber也可以在UI线程收到事件。但这里不能执行耗时操作,否则会出现ANR。

        

3

onEventBackground


        从上面提到的,UI线程是不能执行耗时操作的,所以,EventBus又允许定义新的回调方法onEventBackground回调。在里面执行的代码都会放到子线程执行。因此,这里可以执行耗时的操作等等,但不能执行UI刷新的操作。


4

onEventAsync


        onEventAysnc和onEventBackground都是在非UI线程运行,但两者的区别点就在于onEventAysnc会直接创建新的子线程,但onEventBackground这是根据Publisher所在线程情况:如果是UI线程,则创建子线程,如果是子线程,则直接在当前子线程执行。

        


5运行机制


         我从github上获得关于EventBus的设计图,如下,其中Publisher是消息发送者,Subscriber是消息接受者,Subscriber可以有多个。也即,1对多的关系。而Event这是贯穿整个生命周期的事件,属于被发送的对象,由Publisher创建,通过EventBus这个消息中心传递给Subscriber。

1

EventBus


        通过上述图可以得出结论,EventBus作为消息中心,是独立存在的,它可以贯穿整个程序的生命周期,因此,具体的实现则是以单例的形式存在,这个可以在EventBus.java这个类里面看得到:



        在具体使用时,都需要通过这个getDefault来使用EventBus的功能。


2

Subcriber


        Subscriber即事件接收者,可以是任何的对象,只需调用EventBus.getDefault().register(this); 以下是register的源码


        由于代码太长,我就不做这个搬运工了,省得大家还得去分析源码。我给大家总结一下,这里注册主要做两件事情:

1)通过subscriberMethodFinder来查找这个subscriber里面的回调方法,通过反射方式来获取的,而获取的规则是以onEvent开头的方法(public,且非static等等)

2)再将上面的这些回调方法存储到一个List里面,并将这个列表存在一个Map里,key是subscriber这个对象,value则是上面查找到的回调方法列表。


        通过register注册,我们在不使用的时候,记得取消注册一下。具体可以通过调用EventBus.getDefault().unregister(this)来实现。所谓取消注册,大致上是将这个事件注册的相关信息删除掉。


        注意,我们平时在Activity、Fragment使用的时候,一般在onCreate进行注册,在onDestory的时候,记得取消注册,避免出现内存泄露等情况。


3

Publisher


        Publisher也即事件发送者,作为事件发送者,本身不需要关心自己如何定义和实现的。只需要直接调用Event.getDefault().post()方法,传入事件参数,EventBus再将这个事件参数发送给接收者。

        在EventBus里面,使用ThreadLocal创建了一个线程currentPostingThreadState, 并且在里面维护了事件列表eventQueue。 


        我们调用post的时候,会先将事件event放到eventQueue队列里面。Event再将队列里面的事件一个一个分发出去,直至队列为空,等待下一个事件发送过来。


6更多内容


        前面已经把EventBus详细地介绍了一遍,同时也讲了一下它的内在运行机制,感兴趣的小伙伴可以在github里下载到最新的源码:https://github.com/greenrobot/EventBus


 
Android高级开发 更多文章 Android Studio 入门技巧之<基础篇> Android Studio 之<进阶篇:实用快捷键> Android Studio 之<进阶篇:IDE设置> 2015年度腾讯MIG内部技术峰会 多团队协同开发经验
猜您喜欢 史上最贵的月饼,触动了谁的神经? 「双十一倒计时1天」我们不打折,不优惠,剁手送送送! Bugtags 创业一年总结 每个Linux用户都应该知道的命令行技巧 福利来袭 | 抢邀请码赴技术创新大会——感受曙光的更快、更高、更强!