教你在任何地方使用 EventBus 发送接收消息

EventBusManager是对EventBus的封装,使得在Android应用的任何地方都能方便快捷地订阅和发布消息。它处理了粘性消息和非粘性消息,解决了同一类型粘性消息可能只响应最后一个的问题,通过创建单独的EventBus实例来管理不同类型的粘性事件。BaseSubscriber和BaseStickySubscriber是基础订阅者类,用于接收和处理事件数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不仅仅局限于Activity和Fragment,在任何地方都可用,方便快捷,废话不多说:

EventBusManager 对 EventBus 进行了封装,使得其可以再任何地方订阅接收消息,对于粘性消息和非粘性消息进行了区分处理,由于框架的封装,post的事件类型统一为EventData.class类型,而默认单个EventBus实例内部对于粘性事件是由事件类型进行区分,也就导致在极端场景下同一个EventBus发送了相同类型的粘性消息,只有最后一条消息才会响应的问题,因此发送粘性消息的时候会单独创建一个EventBus实例处理每一类型的粘性消息事件,普通消息则采用默认的EventBus.default实例。
public class EventBusManager {

    /**
     * 保存黏性事件的EventBus对象 
     * 解决默认 EventBus.getDefault() 连续发送黏性事件只有最后一个会生效
     */
    private static final Hashtable<EventKey, EventBus> customEventBusMap = new Hashtable<>();

    private static EventBus getDefaultEventBus() {
        return EventBus.getDefault();
    }

    private static EventBus getCustomEventBus() {
        return new EventBus();
    }

    /**
     * 黏性事件 {@link BaseStickySubscriber}
     * 普通事件 {@link BaseSubscriber}
     */
    public static <T> void register(BaseSubscriber<T> subscriber) {
        if (subscriber instanceof BaseStickySubscriber) {
            EventBus eventBus = getStickyEventBus(subscriber.key);
            if (!eventBus.isRegistered(subscriber)) {
                eventBus.register(subscriber);
            }
        } else {
            if (!getDefaultEventBus().isRegistered(subscriber))
                getDefaultEventBus().register(subscriber);
        }
    }

    /**
     * 取消注册
     */
    public static void unregister(BaseSubscriber<?> subscriber) {
        if (subscriber == null)
            return;
        if (subscriber instanceof BaseStickySubscriber) {
            EventBus eventBus = customEventBusMap.get(subscriber.key);
            if (eventBus != null)
                eventBus.unregister(subscriber);
        } else {
            getDefaultEventBus().unregister(subscriber);
        }
    }

    /**
     * 发送普通事件
     */
    public static <T> void post(EventData<T> eventData) {
        getDefaultEventBus().post(eventData);
    }

    /**
     * 发送黏性事件
     */
    public static <T> void postSticky(EventData<T> eventData) {
        getStickyEventBus(eventData.getKey()).postSticky(eventData);
    }

    private static EventBus getStickyEventBus(EventKey key){
        EventBus eventBus = customEventBusMap.get(key);
        if (eventBus == null) {
            eventBus = getCustomEventBus();
            customEventBusMap.put(key, eventBus);
        }
        return eventBus;
    }
}

BaseSubscriber类为订阅者的基础类,满足接收基本的非粘性消息事件分发,构造函数要求开发者传入对应的事件 KEY 作为标识,用于接受消息事件区分消息来源;onSubscribeEvent方法为EventBus订阅的方法,有Subscribe 注解,如果有特殊需要定制具体Subscribe 参数的需求,继承此类重写即可,该方法接收一个消息事件类型为EventData,EventData内容为为key-value 形式,key即为消息订阅时的key,value为具体数据;接收消息后,通过比对消息的key来确定来源分发给指定订阅者,详情看如下代码:

public abstract class BaseSubscriber<T> {

    protected EventKey key;

    public BaseSubscriber(EventKey key) {
        this.key = key;
    }

    /**
     * 默认 threadMode = ThreadMode.POSTING ,非粘性事件
     * 有需要特殊 Subscribe 的情况, 子类直接覆盖按需实现
     */
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onSubscribeEvent(EventData<T> eventData) {
        if (eventData != null && eventData.getKey() == key) {
            notifyDataChanged(eventData.getValue());

//            Log.e("testBus","事件 key-> "+key+"   eventData key->"+
//                    eventData.getKey() +"    是否相等->"+(key==eventData.getKey()));
        }

    }

    /**
     * -- Subscribe 代理方法 --
     * onSubscribeEvent 匹配到对应事件 下发通知
     * 避免到处写 Subscribe注解
     * --- 如有特殊情况,特殊处理 ---
     *
     * @param value 自定义类型数据
     */
    protected abstract void notifyDataChanged(T value);

BaseStickySubscriber类为订阅者的基础类,满足接收基本的粘性消息事件分发,用法参照BaseSubscriber的基本用法,代码如下:

public abstract class BaseStickySubscriber<T> extends BaseSubscriber<T>{

    public BaseStickySubscriber(EventKey key) {
        super(key);
    }

    @Subscribe(threadMode = ThreadMode.POSTING,sticky = true)
    @Override
    public void onSubscribeEvent(EventData<T> eventData) {
        //Log.e("testBus","黏性事件 key-> "+key+"   eventData key->"+eventData.getKey() +"    是否相等->"+(key==eventData.getKey()));
        super.onSubscribeEvent(eventData);
    }
}

/**
 * 传递的数据 统一格式
 * @param <T> 数据类型
 */
public class EventData<T> {

    private EventKey key;
    private T value;

    public EventData(EventKey key, T value) {
        this.key = key;
        this.value = value;
    }

    public EventKey getKey() {
        return key;
    }

    public T getValue() {
        return value;
    }
}

/**
 * 业务 标识 key
 */
public enum EventKey {

    KEY,
    KEY1,
    KEY2

}

基本用法:

// 发送事件消息,默认非粘性消息

EventBusManager.post(new EventData<>(EventKey.KEY,"value test"));

// 消息订阅者,默认接收非粘性消息

BaseSubscriber<String> subscriber = new BaseSubscriber<String>(EventKey.KEY) {
                    @Override
                    protected void notifyDataChanged(String value) {
                        Log.e("testBus", value);
                    }
                };

 

// 发送事件消息,粘性消息

EventBusManager.postSticky(new EventData<>(EventKey.KEY1,"Sticky value test"));

// 消息订阅者,接收粘性消息

BaseStickySubscriber<String> stickySubscriber = new BaseStickySubscriber<String>(EventKey.KEY1) {
                    @Override
                    protected void notifyDataChanged(String value) {
                        Log.e("testBus", value);
                    }
                };

// 消息注册反注册,通用

EventBusManager.register(subscriber);
EventBusManager.unregister(subscriber);

                EventBusManager.post(new EventData<>(EventKey.KEY,"value test"));
                
                EventBusManager.postSticky(new EventData<>(EventKey.KEY1,"Sticky value test"));


                BaseSubscriber<String> subscriber = new BaseSubscriber<String>(EventKey.KEY) {
                    @Override
                    protected void notifyDataChanged(String value) {
                        Log.e("testBus", value);
                    }
                };

                EventBusManager.register(subscriber);
                
                EventBusManager.unregister(subscriber);


                BaseStickySubscriber<String> stickySubscriber = new BaseStickySubscriber<String>(EventKey.KEY1) {
                    @Override
                    protected void notifyDataChanged(String value) {
                        Log.e("testBus", value);
                    }
                };

                EventBusManager.register(stickySubscriber);
                
                EventBusManager.unregister(stickySubscriber);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值