EventBus的优雅封装


EventBus是一款针对Android优化的发布/订阅事件总线。可以替代广播、startActivityForResult、Handler、异步回调等来实现各组件间、组件与后台线程间的通信。它的优点是开销小,代码更优雅,以及将发送者和接收者解耦。

通常我们在使用EventBus的时候都是直接需要接收通信的Activity/Fragment中通过EventBus.getDefault().register(this)订阅事件,在需要发起通信的逻辑直接调用EventBus.getDefault().post(Object event)来发布事件。但是要是一个项目中有很多地方都使用EventBus来通信,比如重新登录后更新各个页面的登录状态,或者是接收到通知更新消息提示等,都这样直接使用的话代码重复率很高,并且呢,如果以后升级或者更换EventBus时,各个地方都要修改,这就比较麻烦了。因此我一般是将EventBus的发布和订阅封装到BaseActivity/BaseFragment中。

接下来我们开始封装之路:

1、添依赖

在Gradle中添加EventBus依赖:

compile 'org.greenrobot:eventbus:3.0.0'

2、考虑基类中进行绑定

2.1、我们应该这样想,如果在BaseActivity或BaseFragment中定义一抽象方法:

@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的类来说不是很累赘麻烦嘛。

2.2、使用注解

现在想想,使用注解是不是会方便一些呢?

先创建一注解

@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);
    }
}

这样方便多了。

3、对Event的封装

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,如登录、支付等等。以便将来对其分类处理。

4、处理类

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。

5、使用

5.1、Activity或Fragment中

@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注解;

创建接收和处理事件的方法。

5.2、发送消息

Event<ABC> event=new Event<>(0,new ABC());
EventBusUtils.sendEvent(event);

这样就ok了。各位大神有好的建议就告诉我哦。

优质内容筛选与推荐>>
1、(转)平衡树--Splay Tree
2、Spring3系列5-Bean的基本用法
3、LeetCode-最长公共前缀
4、安卓音频简析
5、JavaScript笔记4-数组


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号