EventBus是一款针对Android优化的发布/订阅事件总线。可以替代广播、startActivityForResult、Handler、异步回调等来实现各组件间、组件与后台线程间的通信。它的优点是开销小,代码更优雅,以及将发送者和接收者解耦。
通常我们在使用EventBus的时候都是直接需要接收通信的Activity/Fragment中通过EventBus.getDefault().register(this)订阅事件,在需要发起通信的逻辑直接调用EventBus.getDefault().post(Object event)来发布事件。但是要是一个项目中有很多地方都使用EventBus来通信,比如重新登录后更新各个页面的登录状态,或者是接收到通知更新消息提示等,都这样直接使用的话代码重复率很高,并且呢,如果以后升级或者更换EventBus时,各个地方都要修改,这就比较麻烦了。因此我一般是将EventBus的发布和订阅封装到BaseActivity/BaseFragment中。
接下来我们开始封装之路:
在Gradle中添加EventBus依赖:
compile 'org.greenrobot:eventbus:3.0.0'
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (isRegisterEventBus()) {
EventBusUtil.register(this);
}
}
/**
* 是否注册事件分发
*
* @return true绑定EventBus事件分发,默认不绑定,子类需要绑定的话复写此方法返回true.
*/
protected boolean isRegisterEventBus() {
return false;
}
@Override
public void onDestroy() {
super.onDestroy();
if (isRegisterEventBus()) {
EventBusUtil.unregister(this);
}
}
如上,那岂不所有Base类的子类都需要去实现 isRegisterEventBus 方法,来返回是否绑定EventBus,那对于不绑定EventBus的类来说不是很累赘麻烦嘛。
现在想想,使用注解是不是会方便一些呢?
先创建一注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindEventBus {
}
现在,只要被此注解修饰的类,就表示与EventBus绑定。那么在Base类中:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 若使用BindEventBus注解,则绑定EventBus
if(this.getClass().isAnnotationPresent(BindEventBus.class)){
EventBusUtils.register(this);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
// 若使用BindEventBus注解,则解绑定EventBus
if(this.getClass().isAnnotationPresent(BindEventBus.class)){
EventBusUtils.unregister(this);
}
}
这样方便多了。
public class Event<T> {
private int code;
private T data;
public Event(int code, T data) {
this.code = code;
this.data = data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
Event传入一个泛型T,这里T是具体的事件类,Event是将具体事件与对应业务code进行封装。
再来看下code
public class EventCode {
public static final int A = 0x111111;
public static final int B = 0x222222;
public static final int C = 0x333333;
public static final int D = 0x444444;
}
这里可以定义一些业务相关的code,如登录、支付等等。以便将来对其分类处理。
public class EventBusUtils {
/**
* 绑定 接受者
* @param subscriber
*/
public static void register(Object subscriber) {
EventBus.getDefault().register(subscriber);
}
/**
* 解绑定
* @param subscriber
*/
public static void unregister(Object subscriber){
EventBus.getDefault().unregister(subscriber);
}
/**
* 发送消息(事件)
* @param event
*/
public static void sendEvent(Event event){
EventBus.getDefault().post(event);
}
/**
* 发送 粘性 事件
*
* 粘性事件,在注册之前便把事件发生出去,等到注册之后便会收到最近发送的粘性事件(必须匹配)
* 注意:只会接收到最近发送的一次粘性事件,之前的会接受不到。
* @param event
*/
public static void sendStickyEvent(Event event){
EventBus.getDefault().postSticky(event);
}
}
前两个方法是注册也解注册,已经在Base类中用到了。
sendEvent和sendStickyEvent就是具体的发送消息的方法,注意这里发送的是Event。
@BindEventBus
public class ABCActivity extends BaseActivity {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void handleEvent(Event<ABC> event){
// do something
}
}
继承Base类,使用BindEventBus注解;
创建接收和处理事件的方法。
Event<ABC> event=new Event<>(0,new ABC());
EventBusUtils.sendEvent(event);
这样就ok了。各位大神有好的建议就告诉我哦。