由greenrobot组织贡献(该组织还贡献了greenDAO),一个Android事件发布/订阅轻量级框架,
功能:通过解耦发布者和订阅者简化Android事件传递
EventBus可以代替Android传统的Intent,Handler,Broadcast或接口函式,在Fragment,Activity,Service执行绪之间传递数据,执行方法。
特点:代码简洁,是一种发布订阅设计模式(观察者设计模式)。
EventBus源码下载
基本介绍
- 中文名事件巴士
- 外文名EventBus
- 是否开源是
- 适用平台android
- 作者greenrobot组织
- 作用简化Android事件传递
使用场景
- 用于执行绪间的通讯代替handler或用于组件间的通讯代替Intent
- 广泛用于团购,商城,社交等套用,比如易大师APP,易宸锋Application...
- 实践证明已经有一亿多的APP中集成了EventBus
优势
- 简化了组件间的通讯。
- 分离了事件的传送者和接受者。
- 在Activity、Fragment和执行绪中表现良好。
- 避免了複杂的和易错的依赖关係和生命周期问题。
- 使得代码更简洁,性能更好。
- 更快,更小(约50k的jar包)。
原理图
- EventBus底层採用的是注解和反射的方式来获取订阅方法信息(是注解获取,若注解获取不到,再用反射)
- 当前订阅者是添加到Eventbus 总的事件订阅者的subscriptionByEventType集合中
- 订阅者所有订阅的事件类型添加到typeBySubscriber 中,方便解注册时,移除事件
提示:反射比注解更消耗资源且效率低
基本使用
(一)关联EventBus框架
选中你所要关联的Modules,点击Dependencies,在点击+号,选择library dependency
在输入框中输入eventbus,选择greenrobot公司提供的,进行关联,新建一个Activity(EventBusSendActivity)
(二)在OnCreate注册,在OnDestroy解除注册
提示参数是上下文(你的事件在哪接收,就在哪个类进行EventBus的注册和解除操作.)
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //1. 注册EventBus,参数是上下文. 注意:导入的EventBus请认準org.greenrobot. //注意:有注册就必须有解注册(一般在OnDestroy里执行解注册操作),防止记忆体泄漏,注册一个界面只能注册一次,否则报错 //关于源码我只强调一点:EventBus拿到订阅方法,无法两种手段:1注解 2:反射 EventBus.getDefault().register(MainActivity.this); } @Override protected void onDestroy() { EventBus .getDefault().unregister(MainActivity.this); super.onDestroy(); }
(三)创建EventBus讯息类,设定属性。
提示:EventBus讯息类,一个容器,负责存放一些数据,方便另一个订阅者(接受者),获取讯息
public class EventBusMessage { //定义了传送的讯息必须是String. public String Message; public EventBusMessage(String message) { Message = message; } }
(四)使用EventBus的Post方法传送事件
//4. 使用EventBus传送事件,使用Post方法,参数也必须是EventBus讯息对且要和接收的保持一致 EventBus.getDefault().post(new EventBusMessage("易宸锋,易大师好帅"));
(五)根据讯息类,接收事件
/5接收讯息,参数就是你定义的EventBus讯息类,和传送讯息类必须是同一个
加注解提示:在写接收讯息的方法是,方法名可以自定义,许可权必须是public, 参数必须是一个只要接收的参数类型是一致的,那幺四个方法都可以接收到传送的信息 注释:给人看 注解:给机器看 ThreadMode.MAIN表示这个方法在主执行绪中执行(适合做异步载入,可以将子执行绪载入到数据直接设定到UI界面里)/ @Subscribe(threadMode = ThreadMode.MAIN) public void MessageEventBus(EventBusMessage eventBusMessage){ //在TextView显示接收的讯息,从这个类里拿属性. tv_title.setText(eventBusMessage.Message); Log.d("eventBusThread","ThreadMode.MAIN "+Thread.currentThread().getName()); } //ThreadMode.POSTING表示该方法和讯息传送方在同一个执行绪. @Subscribe(threadMode = ThreadMode.POSTING) public void MessageEventBus1(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.POSTING "+Thread.currentThread().getName()); } /ThreadMode.ASYNC也表示在后台执行(也就是子执行绪执行),可以异步并发处理 (适用于多个执行绪任务处理,内部有执行绪池管理,比如请求网路时,用这个方法,他会自动创建执行绪去请求) 无论发布者是在子执行绪还是主执行绪,该方法都会创建一个子执行绪,在子执行绪执行./ @Subscribe(threadMode = ThreadMode.ASYNC) public void MessageEventBus2(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.ASYNC "+Thread.currentThread().getName()); } //ThreadMode.BACKGROUND表示该方法在后台运行(也就是子执行绪),不能够并发处理 //如果发布者在子执行绪,那幺该方法就在子执行绪执行 //如果发布者在主执行绪,那幺该方法就会创建一个子执行绪,在子执行绪运行. @Subscribe(threadMode = ThreadMode.BACKGROUND) public void MessageEventBus3(EventBusMessage eventBusMessage){ Log.d("eventBusThread","ThreadMode.BACKGROUND "+Thread.currentThread().getName()); }
通过控制台所列印出来的执行绪名,一下输出数据
在主执行绪传送事件 在子执行绪传送事件
main 主执行绪 主执行绪
posting 主执行绪 子执行绪
background 新开一个子执行绪 子执行绪
async 新开一个子执行绪 新开一个子执行绪
黏性事件使用
概念:黏性事件就是指在EventBus内部被快取的那些事件
原理:EventBus为每个类(class)类型保存了最近一次被传送的事件——sticky。后续被传送过来的相同类型的sticky事件会自动替换之前快取的事件。当一个监听者向EventBus进行注册时,它会去请求快取事件。这时,快取的事件就会立即自动传送给这个监听者,有一定的延时性.
使用场景:Android上跨Activity和Fragment生命周期传递数据这种複杂问题,异步调用等等
EventBus的黏性使用方法(EventBus的环境搭建和EventBus基本使用是一致的)
(一)创建EventBus讯息类,设定属性
提示:EventBus讯息类,一个容器,负责存放一些数据,方便另一个订阅者(接受者),获取讯息
public class EventBusStickyMessage { public String message; public EventBusStickyMessage(String message) { this.message = message; } }
(二)传送黏性事件到接收页面
public void send(View view){ EventBus.getDefault().postSticky(new EventBusStickyMessage("易大师,YiChenFeng好帅")); //跳转到传送页面的界面 Intent intent1 = new Intent(MainActivity.this, EventBusReceiveActivity.class); startActivity(intent1); }
(三)接收黏性事件
提示:多了一个属性Sticky,改为true方是启动黏性事件
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) public void EventBusSticky(EventBusStickyMessage eventBusStickyMessage){ tv_title.setText(eventBusStickyMessage.message); }
(四)根据点击事件,得到黏性事件
//做个标记,以防EventBus会进行多次注册boolean flag=true; @Overridepublic void onClick(View v) { //接收黏性数据,实际就是补上注册的环节,容易迷,所以要用心看,注意你一旦注册eventBus就会接收到讯息 if(flag){ //D. EventBus注册广播(),参数是上下文. 导入的EventBus请认準org.greenrobot //注意:有注册就必须有解注册(一般在OnDestroy里执行解注册操作),防止记忆体泄漏,注册一个界面只能注册一次,否则报错 EventBus.getDefault().register(this); //更改标记,使其不会再进行注册,多次注册会报错 flag=false; } }
(五)在onDestroy里解除EventBus注册
// 注意:这里比普通的解除注册还多一步,就是移除黏性事件(是移除所有的还是移除一个,看需求) @Overrideprotected void onDestroy() { //移除所有的黏性事件 EventBus.getDefault().removeAllStickyEvents(); //解除注册 EventBus .getDefault().unregister(this); super.onDestroy(); }