天天看點

自定義一個EventBus

最近公司做的項目是POS點菜機,根據需求發現用EventBus比較麻煩,

(一個消息隻能一個訂閱者接收,我想做的是,一個地方發消息,多處可以同時接收 )

是以就自己寫了一個EventBusPlus

public class EventBusPlus {
    private static final Map<String,Map<String ,SubscriberMethod>> CLASS_REGISTER_EVENT = new ConcurrentHashMap<>();
    private static final Map<String,Map<String ,SubscriberMethod>> TAG_REGISTER_EVENT = new ConcurrentHashMap<>();
    public static final String TAG = EventBusPlus.class.getSimpleName();
    private static EventBusPlus eventBusPlus;

    private EventBusPlus(){}
    public synchronized static EventBusPlus getEventBusPlus(){
        if(eventBusPlus == null){
            synchronized (EventBusPlus.class){
                if(eventBusPlus == null){
                    eventBusPlus = new EventBusPlus();
                }
            }
        }
        return eventBusPlus;
    }

    /**
     * 給指定的類發送消息
     * @param targetClass   目标類的class
     * @param tag
     */
    public void postEventMessageByClass(Class<?> targetClass, String tag, final Object... param){
        if(targetClass == null || tag == null){
            return;
        }
        String className = targetClass.getName();
        if(CLASS_REGISTER_EVENT.containsKey(className)){
            Map<String, SubscriberMethod> subscriberMethodMap = CLASS_REGISTER_EVENT.get(className);
            if(subscriberMethodMap.containsKey(tag)){
                final SubscriberMethod subscriberMethod = subscriberMethodMap.get(tag);
                invokeMethod(subscriberMethod,param);
            }
        }
    }
    /**
     * 給指定多個類發送消息
     * @param targetClasss   目标類的class的數組
     * @param tag   tag标記
     * @param  param 參數
     */
    public void postEventMessageByClass(Class<?>[] targetClasss, String tag, final Object... param){
        if(targetClasss != null){
            for(Class clazz : targetClasss){
                postEventMessageByClass(clazz,tag,param);
            }
        }
    }
    /**
     * 給指定所有tag發送消息
     * @param tag   目标tag
     * @param param 參數
     */
    public void postEventMessageByTag(String tag, final Object... param){
        if(tag == null){
            return;
        }
        if(TAG_REGISTER_EVENT.containsKey(tag)){
            Map<String, SubscriberMethod> subscriberMethodMap = TAG_REGISTER_EVENT.get(tag);
            if(subscriberMethodMap != null && subscriberMethodMap.size() > 0){
                Set<String> keys = subscriberMethodMap.keySet();
                for(String key : keys){
                    SubscriberMethod subscriberMethod = subscriberMethodMap.get(key);
                    invokeMethod(subscriberMethod,param);
                }
            }
        }
    }
    /**
     * 調用方法
     * @param subscriberMethod
     * @param param
     */
    private void invokeMethod(final SubscriberMethod subscriberMethod,final Object... param){
        LogUtil.logD(this.getClass().getSimpleName(),"invokeMethod "+subscriberMethod.getMethod().getName());
        if(subscriberMethod.getThreadMode() == ThreadMode.THREAD_ASYN && Looper.getMainLooper() != Looper.myLooper()){
            //異步處理
            ThreadManager.getInstance().execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        subscriberMethod.getMethod().invoke(subscriberMethod.getObj(),param);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            });
        }else{
            new Handler(Looper.getMainLooper()).post(new Runnable() {
                @Override
                public void run() {
                    try {
                        subscriberMethod.getMethod().invoke(subscriberMethod.getObj(),param);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    /**
     * 注冊監聽
     * @param obj   注冊需要監聽的類
     */
    public synchronized void registerEvent(Object obj){
        if(obj == null){
            Log.e(TAG,"register obj is null");
            return;
        }
        registerSubscriberMethods(obj);
    }
    /**
     * 取消監聽
     * @param obj   取消需要監聽的類
     */
    public synchronized void unRegisterEvent(Object obj){
        if(obj == null){
            Log.e(TAG,"register obj is null");
            return;
        }
        String className = obj.getClass().getName();
        CLASS_REGISTER_EVENT.remove(className);
        Set<String> keys = TAG_REGISTER_EVENT.keySet();
        for(String key : keys){
            Map<String, SubscriberMethod> subscriberMethods = TAG_REGISTER_EVENT.get(key);
            if(subscriberMethods.containsKey(className)){
                TAG_REGISTER_EVENT.get(key).remove(className);
                break;
            }
        }
    }
    /**
     * 查找此對象上所有注冊監聽方法的事件進行注冊
     * @param object   需要查找的類
     * @return
     */
    private synchronized void registerSubscriberMethods(Object object){
        Class<?> subscriberClass = object.getClass();
        String className = subscriberClass.getName();
        Map<String, SubscriberMethod> classSubscriberMethodMap = CLASS_REGISTER_EVENT.get(className);
        Method[] methods = subscriberClass.getDeclaredMethods();
        Map<String, SubscriberMethod> tagSubscriberMethodmap;
        for (Method m: methods) {
            m.setAccessible(true);
            MethodEvent annotation = m.getAnnotation(MethodEvent.class);
            if(annotation != null){
                if(classSubscriberMethodMap == null){
                    classSubscriberMethodMap = new ConcurrentHashMap();
                }
                String tag = annotation.value();
                if(!TAG_REGISTER_EVENT.containsKey(tag)){
                    tagSubscriberMethodmap = new ConcurrentHashMap<>();
                }else{
                    tagSubscriberMethodmap = TAG_REGISTER_EVENT.get(tag);
                }
                ThreadMode threadMode = annotation.threadMode();
                Class<?>[] parameterTypes = m.getParameterTypes();
                SubscriberMethod subscriberMethod = new SubscriberMethod(object,subscriberClass,threadMode,m,parameterTypes,tag);
                classSubscriberMethodMap.put(tag,subscriberMethod);
                //緩存TAG類型的事件
                tagSubscriberMethodmap.put(className,subscriberMethod);
                TAG_REGISTER_EVENT.put(tag,tagSubscriberMethodmap);
            }
        }
        if(classSubscriberMethodMap != null && classSubscriberMethodMap.size() > 0){
            CLASS_REGISTER_EVENT.put(className,classSubscriberMethodMap);
        }
    }
}
           

用法:

1:注冊

基本一樣

EventBusPlus.getEventBusPlus().registerEvent(this);
           

2:發送

EventBusPlus.getEventBusPlus().postEventMessageByClass(OrderDishesActivity.class, "ShoppingFoodListEvent");//重新整理購物車菜品資料
           

如果需要傳參數(參數沒有做限制)

EventBusPlus.getEventBusPlus().postEventMessageByClass(OrderDishesActivity.class, "NormsEvent", foodBean.getId(), position, foodBean);
           

3:接收

@MethodEvent("NormsEvent")
    public void NotifyData() {
   
    }
           

繼續閱讀