Elegant encapsulation of EventBus

EventBus is a publish/subscribe event bus optimized for Android. It can replace broadcast, startActivityForResult, Handler, asynchronous callback, etc. to realize communication between components and between components and background threads. Its advantages are less overhead, more elegant code, and decoupling sender and receiver.

Usually when we use EventBus, we subscribe to events through EventBus.getDefault().register(this) in the Activity/Fragment that directly needs to receive communication, and directly call EventBus.getDefault().post(Object event in the logic that needs to initiate communication ) to publish the event. However, if there are many places in a project that use EventBus to communicate, such as updating the login status of each page after re-login, or receiving notification update message prompts, etc., the code repetition rate is very high, and if When upgrading or replacing the EventBus in the future, all places must be modified, which is more troublesome. Therefore, I generally encapsulate the publication and subscription of EventBus into BaseActivity/BaseFragment.

Next we start the packaging road:

1. Add dependencies

Add the EventBus dependency in Gradle:

compile 'org.greenrobot:eventbus:3.0.0'

2. Consider binding in the base class

2.1. We should think like this, if we define an abstract method in BaseActivity or 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);
    }
}

As above, then all subclasses of the Base class need to implement the isRegisterEventBus method to return whether to bind EventBus, which is not very cumbersome and troublesome for classes that are not bound to EventBus.

2.2, using annotations

Now think about it, is it more convenient to use annotations?

Create an annotation first

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindEventBus {
}

Now, whenever a class is decorated with this annotation, it is bound to EventBus. Then in the Base class:

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

This is much more convenient.

3. Encapsulation of 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 passes in a generic T, where T is the specific event class, and Event is the encapsulation of the specific event and the corresponding business code.

Let's look at the code again

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;

}

Here you can define some business-related codes, such as login, payment, etc. for future classification.

4. Processing class

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

The first two methods are registration and deregistration, which have been used in the Base class.

sendEvent and sendStickyEvent are the specific methods of sending messages. Note that Event is sent here.

5. Use

5.1, in Activity or 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
    }
}

Inherit the Base class and use the BindEventBus annotation;

Create methods to receive and handle events.

5.2. Sending a message

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

That's ok. If you have any good suggestions, please let me know.

For more exciting content, pay attention to my WeChat public account - Android Motor Vehicles .
write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325560403&siteId=291194637