Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处。
EventBus对于Android开发老司机来说肯定不会陌生,它是一个基于观察者模式的事件发布/订阅框架,开发者可以通过极少的代码去实现多个模块之间的通信,而不需要以层层传递接口的形式去单独构建通信桥梁。从而降低因多重回调导致的模块间强耦合,同时避免产生大量内部类。它拥有使用方便,性能高,接入成本低和支持多线程的优点,实乃模块解耦、代码重构必备良药。

作为Markus Junginger大神耗时4年打磨、超过1亿接入量、Github 9000+ star的明星级组件,分析EventBus的文章早已是数不胜数。本文的题目是“教你飙巴士”,而这辆Bus之所以可以飙起来,是因为作者在EventBus 3中引入了EventBusAnnotationProcessor(注解分析生成索引)技术,大大提高了EventBus的运行效率。而分析这个加速器的资料在网上很少,因此本文会把重点放在分析这个EventBus 3的新特性上,同时分享一些踩坑经验,并结合源码分析及UML图,以直观的形式和大家一起学习EventBus 3的用法及运行原理。
1. 新手上路——使用EventBus

1.1 导入组件:
打开App的build.gradle,在dependencies中添加最新的EventBus依赖:
compile 'org.greenrobot:eventbus:3.0.0'
如果不需要索引加速的话,就可以直接跳到第二步了。而要应用最新的EventBusAnnotationProcessor则比较麻烦,因为注解解析依赖于android-apt-plugin。我们一步一步来,首先在项目gradle的dependencies中引入apt编译插件:
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
然后在App的build.gradle中应用apt插件,并设置apt生成的索引的包名和类名:
apply plugin: 'com.neenbedankt.android-apt'
apt {
arguments {
eventBusIndex "com.study.sangerzhong.studyapp.MyEventBusIndex"
}
}
接着在App的dependencies中引入EventBusAnnotationProcessor:
apt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
这里需要注意,如果应用了EventBusAnnotationProcessor却没有设置arguments的话,编译时就会报错:
No option eventBusIndex passed to annotation processor
此时需要我们先编译一次,生成索引类。编译成功之后,就会发现在\ProjectName\app\build\generated\source\apt\PakageName\下看到通过注解分析生成的索引类,这样我们便可以在初始化EventBus时应用我们生成的索引了。
1.2 初始化EventBus
EventBus默认有一个单例,可以通过getDefault()获取,也可以通过EventBus.builder()构造自定义的EventBus,比如要应用我们生成好的索引时:
EventBus mEventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();
如果想把自定义的设置应用到EventBus默认的单例中,则可以用installDefaultEventBus()方法:
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
1.3 定义事件:
所有能被实例化为Object的实例都可以作为事件:
public class DriverEvent { public String info; }
在最新版的eventbus 3中如果用到了索引加速,事件类的修饰符必须为public,不然编译时会报错:Subscriber method must be public
1.4 监听事件:
首先把作为订阅事件的模块通过EventBus注册监听:
mEventBus.register(this);
在3.0之前,注册监听需要区分是否监听黏性(sticky)事件,监听EventBus事件的模块需要实现以onEvent开头的方法。如今改为在方法上添加注解的形式:
@Subscribe(threadMode = ThreadMode.POSTING, priority = 0, sticky = true)
public void handleEvent(DriverEvent event) {
Log.d(TAG, event.info);
}
注解有三个参数,threadMode为回调所在的线程,priority为优先级,sticky为是否接收黏性事件。调度单位从类细化到了方法,对方法的命名也没有了要求,方便混淆代码。但注册了监听的模块必须有一个标注了Subscribe注解方法,不然在register时会抛出异常:
Subscriber class XXX and its super classes have no public methods with the @Subscribe annotation
1.5 发送事件:
调用post或者postSticky即可:
mEventBus.post(new DriverEvent("magnet:?xt=urn:btih……"));
到此我们就完成了使用EventBus的学习,可以在代码中尽情地飚车了。项目接入了EventBus之后会有什么好处呢?举一个常见的用例:ViewPager中Fragment的相互通信,就不需要在容器中定义各种接口,可以直接通过EventBus来实现相互回调,这样就把逻辑从ViewPager这个容器中剥离出来,使代码阅读起来更加直观。
在实际项目的使用中,register和unregister通常与Activity和Fragment的生命周期相关,ThreadMode.MainThread可以很好地解决Android的界面刷新必须在UI线程的问题,不需要再回调后用Handler中转(EventBus中已经自动用Handler做了处

本文详细介绍了EventBus3的使用方法、运行原理及新特性,包括如何使用注解加速器提高性能,以及在实际项目中遇到的问题与解决策略。通过分析EventBus的核心架构与工作原理,读者能够深入了解其在模块解耦、代码重构中的优势,以及如何避免常见陷阱,成为高效、专业的Android开发老司机。
最低0.47元/天 解锁文章
2091

被折叠的 条评论
为什么被折叠?



