给EventBus发的消息加个id来区分

4,732 阅读2分钟

背景

在小型的项目当中,接入EventBus不失为一种好的解耦方式,同时也很好的避免了多余的接口代码的编写,发送方只管将消息发出,而不用去管对应消息类型的接收方怎么处理。

然而,在使用过程中,也难免遇上了一些不好用的特性。

EventBus可以通过@Subscribe注解来声明接收方方法。发送方和接收方的对应是通过发送的数据的类来做的。

发送方发送一个String类型的消息,那么在注册了的订阅者中,被@Subscribe注解的所有String参数和Object参数的方法都是可以收到这个消息的。

一方面,这样导致了发送者和接收者的关系不够直观,另一方面,如果真要传递String类型,却不想被订阅者的某些String参数方法收到,是无法做到的。所以,在参数类型来分配接收者的基础下,我认为还需要加一个维度来区分消息。

改进

基于EventBus开源的3.0.0的代码,我对其做出适当修改,给@Subscribe注解增加了一个int类型的id属性,同时给EventBus类重载了post(int,Object)方法,使得接收方可以这样注解自己的方法:

@Subscribe(id = 1)
public void print(String message){
    Log.i("tag",message);
}

@Subscribe(id = 2)
public void setMessage(String message){
    this.mMessage = message;
}

然后发送方可以这样发送自己的消息:

EventBus.getDefault().post(1,"hello world!");

这样,尽管接收String类型的方法有两个,但是由于发送的消息id是1,所以,只有print方法会收到消息并执行。

当然,EventBus原汁原味的不加id的方式也是保留的,你可以不给接收放指定id,也不在发送的时候使用id参数,这样依旧是所有同参数类型的接收者都会执行。如下。

...
@Override
protected void onCreate(Bundle savedInstanceState) {
    EventBus.getDefault().post("hello world");
}

@Subscribe
public void print(String message){
    Log.i("tag",message);
}

使用

先放GitHub源码链接

1. 添加JitPack仓库链接到根项目的build.gradle:

allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

2. 在module的build.gradle中添加依赖

dependencies {
    implementation 'com.github.lizhengxian1991.eventbusplus:eventbus:1.0.0'
    annotationProcessor 'com.github.lizhengxian1991.eventbusplus:eventbus-annotation-processor:1.0.0'
}

3. 在module的build.gradle中增加Processor参数,指定生成的Eventbus的索引类名(替换<Your index class name>

android {
    ...
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [ eventBusIndex : '<Your index class name>' ]
            }
        }
    }
}

4. 在Application的onCreate方法中初始化索引(将`<Your index class name>替换为3中定义的类)

EventBus.builder().addIndex(new <Your index class name>()).installDefaultEventBus();

其他使用方式同原版EventBus 3.0.0版本一致,通过EventBus.getDefault().register(subscriber)来注册消息接收者对象,然后就可以尽情的post和subscribe啦!