最近公司做的項目是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() {
}