From 8226e507dae75777e525f5a0017549562e697a9e Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 10 Dec 2015 16:05:06 +0800 Subject: [PATCH 1/7] =?UTF-8?q?1.=E5=AF=B9=E6=97=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E7=9A=84=E6=94=AF=E6=8C=81=202.=E5=AF=B9?= =?UTF-8?q?=E5=A4=9A=E5=8F=82=E6=95=B0=E6=96=B9=E6=B3=95=E7=9A=84=E6=94=AF?= =?UTF-8?q?=E6=8C=81=203.sticky=E5=8F=AF=E4=BB=A5=E6=94=AF=E6=8C=81post?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=204.=E4=BA=8B=E4=BB=B6post=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=E4=BC=9A=E8=A2=AB=E6=B6=88=E8=80=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/simple/eventbus/EventBus.java | 264 ++++++++++-------- src/org/simple/eventbus/EventType.java | 45 ++- src/org/simple/eventbus/NULL.java | 12 + .../eventbus/SubsciberMethodHunter.java | 92 +++--- src/org/simple/eventbus/Subscription.java | 11 +- src/org/simple/eventbus/TargetMethod.java | 11 +- .../eventbus/handler/AsyncEventHandler.java | 2 +- .../eventbus/handler/DefaultEventHandler.java | 6 +- .../simple/eventbus/handler/EventHandler.java | 2 +- .../handler/UIThreadEventHandler.java | 2 +- .../matchpolicy/DefaultMatchPolicy.java | 35 ++- .../eventbus/matchpolicy/MatchPolicy.java | 2 +- .../matchpolicy/StrictMatchPolicy.java | 2 +- 13 files changed, 273 insertions(+), 213 deletions(-) create mode 100644 src/org/simple/eventbus/NULL.java diff --git a/src/org/simple/eventbus/EventBus.java b/src/org/simple/eventbus/EventBus.java index 851f969..5079eed 100644 --- a/src/org/simple/eventbus/EventBus.java +++ b/src/org/simple/eventbus/EventBus.java @@ -26,6 +26,7 @@ import org.simple.eventbus.matchpolicy.MatchPolicy; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; @@ -37,28 +38,28 @@ import java.util.concurrent.CopyOnWriteArrayList; /** - *

+ *

* EventBus是AndroidEventBus框架的核心类,也是用户的入口类.它存储了用户注册的订阅者信息和方法, * 事件类型和该事件对应的tag标识一个种类的事件{@see EventType},每一种事件对应有一个或者多个订阅者{@see Subscription} * ,订阅者中的订阅函数通过{@see Subcriber}注解来标识tag和线程模型,这样使得用户体检较为友好,代码也更加整洁. - *

+ *

* 用户需要在发布事件前通过@{@see #register(Object)}方法将订阅者注册到EventBus中,EventBus会解析该订阅者中使用了 * {@see Subcriber}标识的函数,并且将它们以{@see EventType}为key,以{@see Subscription} * 列表为value存储在map中. 当用户post一个事件时通过事件到map中找到对应的订阅者,然后按照订阅函数的线程模型将函数执行在对应的线程中. - *

+ *

* 最后在不在需要订阅事件时,应该调用{@see #unregister(Object)}函数注销该对象,避免内存泄露! * 例如在Activity或者Fragment的onDestory函数中注销对Activity或者Fragment的订阅. - *

+ *

* 注意 : 如果发布的事件的参数类型是订阅的事件参数的子类,订阅函数默认也会被执行。例如你在订阅函数中订阅的是List类型的事件, * 但是在发布时发布的是ArrayList的事件, * 因此List是一个泛型抽象,而ArrayList才是具体的实现 * ,因此这种情况下订阅函数也会被执行。如果你需要订阅函数能够接收到的事件类型必须严格匹配 ,你可以构造一个EventBusConfig对象, * 然后设置MatchPolicy然后在使用事件总线之前使用该EventBusConfig来初始化事件总线. - * EventBusConfig config = new EventBusConfig(); - config.setMatchPolicy(new StrictMatchPolicy()); - EventBus.getDefault().initWithConfig(config); + * EventBusConfig config = new EventBusConfig(); + * config.setMatchPolicy(new StrictMatchPolicy()); + * EventBus.getDefault().initWithConfig(config); * - * + * * @author mrsimple */ public final class EventBus { @@ -67,45 +68,42 @@ public final class EventBus { * default descriptor */ private static final String DESCRIPTOR = EventBus.class.getSimpleName(); - /** - * 事件总线描述符描述符 + * The Default EventBus instance */ - private String mDesc = DESCRIPTOR; - + private static EventBus sDefaultBus; /** * EventType-Subcriptions map */ private final Map> mSubcriberMap = new ConcurrentHashMap>(); - /** - * - */ - private List mStickyEvents = Collections - .synchronizedList(new LinkedList()); /** * the thread local event queue, every single thread has it's own queue. */ ThreadLocal> mLocalEvents = new ThreadLocal>() { protected java.util.Queue initialValue() { return new ConcurrentLinkedQueue(); - }; - }; + } + ; + }; /** * the event dispatcher */ EventDispatcher mDispatcher = new EventDispatcher(); - /** * the subscriber method hunter, find all of the subscriber's methods * annotated with @Subcriber */ SubsciberMethodHunter mMethodHunter = new SubsciberMethodHunter(mSubcriberMap); - /** - * The Default EventBus instance + * 事件总线描述符描述符 */ - private static EventBus sDefaultBus; + private String mDesc = DESCRIPTOR; + /** + * + */ + private List mStickyEvents = Collections + .synchronizedList(new LinkedList()); /** * private Constructor @@ -116,7 +114,7 @@ private EventBus() { /** * constructor with desc - * + * * @param desc the descriptor of eventbus */ public EventBus(String desc) { @@ -137,11 +135,22 @@ public static EventBus getDefault() { return sDefaultBus; } + /** + * 以sticky的形式注册,则会在注册成功之后迭代所有的sticky事件 + * + * @param subscriber + */ + public void registerSticky(Object subscriber) { + this.register(subscriber); + // 处理sticky事件 + mDispatcher.dispatchStickyEvents(subscriber); + } + /** * register a subscriber into the mSubcriberMap, the key is subscriber's * method's name and tag which annotated with {@see Subcriber}, the value is * a list of Subscription. - * + * * @param subscriber the target subscriber */ public void register(Object subscriber) { @@ -154,17 +163,6 @@ public void register(Object subscriber) { } } - /** - * 以sticky的形式注册,则会在注册成功之后迭代所有的sticky事件 - * - * @param subscriber - */ - public void registerSticky(Object subscriber) { - this.register(subscriber); - // 处理sticky事件 - mDispatcher.dispatchStickyEvents(subscriber); - } - /** * @param subscriber */ @@ -179,68 +177,100 @@ public void unregister(Object subscriber) { /** * post a event - * + * * @param event */ - public void post(Object event) { - post(event, EventType.DEFAULT_TAG); + public void post(Object... event) { + post(EventType.DEFAULT_TAG, event); } /** * 发布事件 - * + * * @param event 要发布的事件 - * @param tag 事件的tag, 类似于BroadcastReceiver的action + * @param tag 事件的tag, 类似于BroadcastReceiver的action */ - public void post(Object event, String tag) { - if (event == null) { - Log.e(this.getClass().getSimpleName(), "The event object is null"); - return; + public void post(String tag, Object... event) { + if (event == null || event.length == 0) { + mLocalEvents.get().offer(new EventType(tag, new NULL().getClass())); + mDispatcher.dispatchEvents(new NULL()); + } else { + Class[] c = new Class[event.length]; + for (int i = 0; i < event.length; i++) { + Object o = event[i]; + if (o == null) + o = new NULL(); + c[i] = o.getClass(); + } + mLocalEvents.get().offer(new EventType(tag, c)); + mDispatcher.dispatchEvents(event); } - mLocalEvents.get().offer(new EventType(event.getClass(), tag)); - mDispatcher.dispatchEvents(event); } /** * 发布Sticky事件,tag为EventType.DEFAULT_TAG - * + * * @param event */ - public void postSticky(Object event) { - postSticky(event, EventType.DEFAULT_TAG); + public void postSticky(Object... event) { + postSticky(EventType.DEFAULT_TAG, event); } /** * 发布含有tag的Sticky事件 - * + * * @param event 事件 - * @param tag 事件tag + * @param tag 事件tag */ - public void postSticky(Object event, String tag) { - if (event == null) { - Log.e(this.getClass().getSimpleName(), "The event object is null"); - return; + public void postSticky(String tag, Object... event) { + if (event == null || event.length == 0) { + EventType eventType = new EventType(tag, new NULL().getClass()); + eventType.event = event; + mStickyEvents.add(eventType); + mLocalEvents.get().offer(eventType); + mDispatcher.dispatchEvents(event); + } else { + Class[] c = new Class[event.length]; + for (int i = 0; i < event.length; i++) { + Object o = event[i]; + if (o == null) + o = new NULL(); + c[i] = o.getClass(); + } + EventType eventType = new EventType(tag, c); + mStickyEvents.add(eventType); + mLocalEvents.get().offer(eventType); + mDispatcher.dispatchEvents(event); } - EventType eventType = new EventType(event.getClass(), tag); - eventType.event = event; - mStickyEvents.add(eventType); } - public void removeStickyEvent(Class eventClass) { - removeStickyEvent(eventClass, EventType.DEFAULT_TAG); + public void removeStickyEvent(Class... eventClass) { + removeStickyEvent(EventType.DEFAULT_TAG, eventClass); } /** * 移除Sticky事件 - * - * @param type + * + * @param eventClass */ - public void removeStickyEvent(Class eventClass, String tag) { + public void removeStickyEvent(String tag, Class... eventClass) { + EventType other; + if (eventClass == null || eventClass.length == 0) { + other = new EventType(tag, new NULL().getClass()); + } else { + Class[] c = new Class[eventClass.length]; + for (int i = 0; i < eventClass.length; i++) { + Object o = eventClass[i]; + if (o == null) + o = new NULL(); + c[i] = o.getClass(); + } + other = new EventType(tag, c); + } Iterator iterator = mStickyEvents.iterator(); while (iterator.hasNext()) { EventType eventType = iterator.next(); - if (eventType.paramClass.equals(eventClass) - && eventType.tag.equals(tag)) { + if (eventType.equals(other)) { iterator.remove(); } } @@ -252,7 +282,7 @@ public List getStickyEvents() { /** * 设置订阅函数匹配策略 - * + * * @param policy 匹配策略 */ public void setMatchPolicy(MatchPolicy policy) { @@ -261,7 +291,7 @@ public void setMatchPolicy(MatchPolicy policy) { /** * 设置执行在UI线程的事件处理器 - * + * * @param handler */ public void setUIThreadEventHandler(EventHandler handler) { @@ -270,7 +300,7 @@ public void setUIThreadEventHandler(EventHandler handler) { /** * 设置执行在post线程的事件处理器 - * + * * @param handler */ public void setPostThreadHandler(EventHandler handler) { @@ -279,7 +309,7 @@ public void setPostThreadHandler(EventHandler handler) { /** * 设置执行在异步线程的事件处理器 - * + * * @param handler */ public void setAsyncEventHandler(EventHandler handler) { @@ -288,7 +318,7 @@ public void setAsyncEventHandler(EventHandler handler) { /** * 返回订阅map - * + * * @return */ public Map> getSubscriberMap() { @@ -297,7 +327,7 @@ public Map> getSubscriberMap() { /** * 获取等待处理的事件队列 - * + * * @return */ public Queue getEventQueue() { @@ -314,7 +344,7 @@ public synchronized void clear() { /** * get the descriptor of EventBus - * + * * @return the descriptor of EventBus */ public String getDescriptor() { @@ -327,7 +357,7 @@ public EventDispatcher getDispatcher() { /** * 事件分发器 - * + * * @author mrsimple */ private class EventDispatcher { @@ -346,20 +376,19 @@ private class EventDispatcher { * 异步线程中执行订阅方法 */ EventHandler mAsyncEventHandler = new AsyncEventHandler(); - - /** - * 缓存一个事件类型对应的可EventType列表 - */ - private Map> mCacheEventTypes = new ConcurrentHashMap>(); /** * 事件匹配策略,根据策略来查找对应的EventType集合 */ MatchPolicy mMatchPolicy = new DefaultMatchPolicy(); + /** + * 缓存一个事件类型对应的可EventType列表 + */ + private Map> mCacheEventTypes = new ConcurrentHashMap>(); /** - * @param event + * @param aEvent */ - void dispatchEvents(Object aEvent) { + void dispatchEvents(Object... aEvent) { Queue eventsQueue = mLocalEvents.get(); while (eventsQueue.size() > 0) { deliveryEvent(eventsQueue.poll(), aEvent); @@ -368,28 +397,42 @@ void dispatchEvents(Object aEvent) { /** * 根据aEvent查找到所有匹配的集合,然后处理事件 - * + * * @param type * @param aEvent */ - private void deliveryEvent(EventType type, Object aEvent) { + private void deliveryEvent(EventType type, Object... aEvent) { // 如果有缓存则直接从缓存中取 List eventTypes = getMatchedEventTypes(type, aEvent); // 迭代所有匹配的事件并且分发给订阅者 for (EventType eventType : eventTypes) { handleEvent(eventType, aEvent); } + mCacheEventTypes.remove(type); + } + + private List getMatchedEventTypes(EventType type, Object... aEvent) { + List eventTypes = null; + // 如果有缓存则直接从缓存中取 + if (mCacheEventTypes.containsKey(type)) { + eventTypes = mCacheEventTypes.get(type); + } else { + eventTypes = mMatchPolicy.findMatchEventTypes(type, aEvent); + mCacheEventTypes.put(type, eventTypes); + } + + return eventTypes != null ? eventTypes : new ArrayList(); } /** * 处理单个事件 - * + * * @param eventType * @param aEvent */ - private void handleEvent(EventType eventType, Object aEvent) { - List subscriptions = mSubcriberMap.get(eventType); - if (subscriptions == null) { + private void handleEvent(EventType eventType, Object... aEvent) { + List subscriptions = loadMapKey(mSubcriberMap, eventType); + if (subscriptions == null || subscriptions.size() == 0) { return; } @@ -401,17 +444,24 @@ private void handleEvent(EventType eventType, Object aEvent) { } } - private List getMatchedEventTypes(EventType type, Object aEvent) { - List eventTypes = null; - // 如果有缓存则直接从缓存中取 - if (mCacheEventTypes.containsKey(type)) { - eventTypes = mCacheEventTypes.get(type); - } else { - eventTypes = mMatchPolicy.findMatchEventTypes(type, aEvent); - mCacheEventTypes.put(type, eventTypes); + private List loadMapKey(Map> mSubcriberMap, EventType eventType) { + List result = new ArrayList(); + for (EventType key : mSubcriberMap.keySet()) { + if (key.equals(eventType)) { + result.addAll(mSubcriberMap.get(key)); + } } + return result; + } - return eventTypes != null ? eventTypes : new ArrayList(); + private EventHandler getEventHandler(ThreadMode mode) { + if (mode == ThreadMode.ASYNC) { + return mAsyncEventHandler; + } + if (mode == ThreadMode.POST) { + return mPostThreadHandler; + } + return mUIThreadEventHandler; } void dispatchStickyEvents(Object subscriber) { @@ -422,16 +472,16 @@ void dispatchStickyEvents(Object subscriber) { /** * 处理单个Sticky事件 - * + * * @param eventType - * @param aEvent + * @param subscriber */ private void handleStickyEvent(EventType eventType, Object subscriber) { List eventTypes = getMatchedEventTypes(eventType, eventType.event); // 事件 Object event = eventType.event; for (EventType foundEventType : eventTypes) { - Log.e("", "### 找到的类型 : " + foundEventType.paramClass.getSimpleName() + Log.e("", "### 找到的类型 : " + foundEventType.paramClass.toString() + ", event class : " + event.getClass().getSimpleName()); final List subscriptions = mSubcriberMap.get(foundEventType); if (subscriptions == null) { @@ -442,9 +492,7 @@ private void handleStickyEvent(EventType eventType, Object subscriber) { EventHandler eventHandler = getEventHandler(mode); // 如果订阅者为空,那么该sticky事件分发给所有订阅者.否则只分发给该订阅者 if (isTarget(subItem, subscriber) - && (subItem.eventType.equals(foundEventType) - || subItem.eventType.paramClass - .isAssignableFrom(foundEventType.paramClass))) { + && (subItem.eventType.equals(foundEventType))) { // 处理事件 eventHandler.handleEvent(subItem, event); } @@ -454,7 +502,7 @@ private void handleStickyEvent(EventType eventType, Object subscriber) { /** * 如果传递进来的订阅者不为空,那么该Sticky事件只传递给该订阅者(注册时),否则所有订阅者都传递(发布时). - * + * * @param item * @param subscriber * @return @@ -464,16 +512,6 @@ private boolean isTarget(Subscription item, Object subscriber) { return subscriber == null || (subscriber != null && cacheObject != null && cacheObject.equals(subscriber)); } - - private EventHandler getEventHandler(ThreadMode mode) { - if (mode == ThreadMode.ASYNC) { - return mAsyncEventHandler; - } - if (mode == ThreadMode.POST) { - return mPostThreadHandler; - } - return mUIThreadEventHandler; - } } // end of EventDispatcher } diff --git a/src/org/simple/eventbus/EventType.java b/src/org/simple/eventbus/EventType.java index a41c635..4203dd9 100644 --- a/src/org/simple/eventbus/EventType.java +++ b/src/org/simple/eventbus/EventType.java @@ -16,11 +16,13 @@ package org.simple.eventbus; +import java.util.Arrays; + /** - *

+ *

* 该类是描述一个函数唯一性的对象,参数类型、tag两个条件保证了对象的唯一性.通过该类的对象来查找注册了相应类型和tag的所有订阅者{@see * Subscription}, 并且在接到消息时调用所有订阅者对应的函数. - * + * * @author mrsimple */ public final class EventType { @@ -28,43 +30,28 @@ public final class EventType { * 默认的tag */ public static final String DEFAULT_TAG = "default_tag"; - - /** - * 参数类型 - */ - Class paramClass; /** * 函数的tag */ public String tag = DEFAULT_TAG; + public Object event; + /** + * 参数类型 + */ + Class[] paramClass; - public Object event ; /** * @param aClass */ - public EventType(Class aClass) { - this(aClass, DEFAULT_TAG); + public EventType(Class... aClass) { + this(DEFAULT_TAG, aClass); } - public EventType(Class aClass, String aTag) { + public EventType(String aTag, Class... aClass) { paramClass = aClass; tag = aTag; } - @Override - public String toString() { - return "EventType [paramClass=" + paramClass.getName() + ", tag=" + tag + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((paramClass == null) ? 0 : paramClass.hashCode()); - result = prime * result + ((tag == null) ? 0 : tag.hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) @@ -77,7 +64,8 @@ public boolean equals(Object obj) { if (paramClass == null) { if (other.paramClass != null) return false; - } else if (!paramClass.equals(other.paramClass)) +// } else if (!paramClass.equals(other.paramClass)) + } else if (!Arrays.equals(paramClass, other.paramClass)) return false; if (tag == null) { if (other.tag != null) @@ -87,4 +75,9 @@ public boolean equals(Object obj) { return true; } + @Override + public String toString() { + return "EventType [paramClass=" + (paramClass != null ? paramClass.length : 0) + ", tag=" + tag + "]"; + } + } diff --git a/src/org/simple/eventbus/NULL.java b/src/org/simple/eventbus/NULL.java new file mode 100644 index 0000000..3bb8f7d --- /dev/null +++ b/src/org/simple/eventbus/NULL.java @@ -0,0 +1,12 @@ +package org.simple.eventbus; + +/** + * Created by xujian on 15/11/18. + */ +public class NULL { + private Object value = null; + + public Object getValue() { + return value; + } +} diff --git a/src/org/simple/eventbus/SubsciberMethodHunter.java b/src/org/simple/eventbus/SubsciberMethodHunter.java index ed7c73d..0b6b437 100644 --- a/src/org/simple/eventbus/SubsciberMethodHunter.java +++ b/src/org/simple/eventbus/SubsciberMethodHunter.java @@ -36,7 +36,7 @@ /** * the subscriber method hunter, find all of the subscriber's methods which * annotated with @Subcriber. - * + * * @author mrsimple */ public class SubsciberMethodHunter { @@ -55,7 +55,7 @@ public SubsciberMethodHunter(Map> /** * 查找订阅对象中的所有订阅函数,订阅函数的参数只能有一个.找到订阅函数之后构建Subscription存储到Map中 - * + * * @param subscriber 订阅对象 * @return */ @@ -75,25 +75,71 @@ public void findSubcribeMethods(Object subscriber) { // 获取方法参数 Class[] paramsTypeClass = method.getParameterTypes(); // 订阅函数只支持一个参数 - if (paramsTypeClass != null && paramsTypeClass.length == 1) { - Class paramType = convertType(paramsTypeClass[0]); - EventType eventType = new EventType(paramType, annotation.tag()); + if (paramsTypeClass != null && paramsTypeClass.length == 0) { + Class paramType = NULL.class; + EventType eventType = new EventType(annotation.tag(), paramType); + TargetMethod subscribeMethod = new TargetMethod(method, eventType, + annotation.mode()); + subscibe(eventType, subscribeMethod, subscriber); + } else if (paramsTypeClass != null && paramsTypeClass.length > 0 ) { + Class[] transform = new Class[paramsTypeClass.length]; + for (int j = 0; j < paramsTypeClass.length; j++) { + Class sub = paramsTypeClass[j]; + transform[j] = convertType(sub); + } + EventType eventType = new EventType(annotation.tag(), transform); TargetMethod subscribeMethod = new TargetMethod(method, eventType, annotation.mode()); subscibe(eventType, subscribeMethod, subscriber); } } } // end for - // 获取父类,以继续查找父类中符合要求的方法 + // 获取父类,以继续查找父类中符合要求的方法 clazz = clazz.getSuperclass(); } } + private boolean isSystemCalss(String name) { + return name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android."); + } + + /** + * if the subscriber method's type is primitive, convert it to corresponding + * Object type. for example, int to Integer. + * + * @param eventType origin Event Type + * @return + */ + private Class convertType(Class eventType) { + Class returnClass = eventType; + if (eventType.equals(boolean.class)) { + returnClass = Boolean.class; + } else if (eventType.equals(int.class)) { + returnClass = Integer.class; + } else if (eventType.equals(float.class)) { + returnClass = Float.class; + } else if (eventType.equals(double.class)) { + returnClass = Double.class; + } else if (eventType.equals(long.class)) { + returnClass = Long.class; + } else if (eventType.equals(short.class)) { + returnClass = Short.class; + } else if (eventType.equals(byte.class)) { + returnClass = Byte.class; + } else if (eventType.equals(char.class)) { + returnClass = Character.class; + } else if (eventType.equals(void.class)) { + returnClass = Void.class; + } + + return returnClass; + } + /** * 按照EventType存储订阅者列表,这里的EventType就是事件类型,一个事件对应0到多个订阅者. - * - * @param event 事件 - * @param method 订阅方法对象 + * + * @param event 事件 + * @param method 订阅方法对象 * @param subscriber 订阅者 */ private void subscibe(EventType event, TargetMethod method, Object subscriber) { @@ -114,7 +160,7 @@ private void subscibe(EventType event, TargetMethod method, Object subscriber) { /** * remove subscriber methods from map - * + * * @param subscriber */ public void removeMethodsFromMap(Object subscriber) { @@ -153,30 +199,4 @@ private boolean isObjectsEqual(Object cachedObj, Object subscriber) { && cachedObj.equals(subscriber); } - /** - * if the subscriber method's type is primitive, convert it to corresponding - * Object type. for example, int to Integer. - * - * @param eventType origin Event Type - * @return - */ - private Class convertType(Class eventType) { - Class returnClass = eventType; - if (eventType.equals(boolean.class)) { - returnClass = Boolean.class; - } else if (eventType.equals(int.class)) { - returnClass = Integer.class; - } else if (eventType.equals(float.class)) { - returnClass = Float.class; - } else if (eventType.equals(double.class)) { - returnClass = Double.class; - } - - return returnClass; - } - - private boolean isSystemCalss(String name) { - return name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android."); - } - } diff --git a/src/org/simple/eventbus/Subscription.java b/src/org/simple/eventbus/Subscription.java index 835000c..0061925 100644 --- a/src/org/simple/eventbus/Subscription.java +++ b/src/org/simple/eventbus/Subscription.java @@ -45,7 +45,7 @@ public class Subscription { /** * @param subscriber - * @param method + * @param targetMethod */ public Subscription(Object subscriber, TargetMethod targetMethod) { this.subscriber = new WeakReference(subscriber); @@ -54,15 +54,6 @@ public Subscription(Object subscriber, TargetMethod targetMethod) { this.eventType = targetMethod.eventType; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((subscriber == null) ? 0 : subscriber.hashCode()); - result = prime * result + ((targetMethod == null) ? 0 : targetMethod.hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) diff --git a/src/org/simple/eventbus/TargetMethod.java b/src/org/simple/eventbus/TargetMethod.java index 09c2e71..8624c1a 100644 --- a/src/org/simple/eventbus/TargetMethod.java +++ b/src/org/simple/eventbus/TargetMethod.java @@ -40,7 +40,7 @@ class TargetMethod { /** * @param md - * @param eventType + * @param type * @param mode */ public TargetMethod(Method md, EventType type, ThreadMode mode) { @@ -50,15 +50,6 @@ public TargetMethod(Method md, EventType type, ThreadMode mode) { this.threadMode = mode; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((eventType == null) ? 0 : eventType.hashCode()); - result = prime * result + ((method == null) ? 0 : method.getName().hashCode()); - return result; - } - @Override public boolean equals(Object obj) { if (this == obj) diff --git a/src/org/simple/eventbus/handler/AsyncEventHandler.java b/src/org/simple/eventbus/handler/AsyncEventHandler.java index 69bab28..f18864a 100644 --- a/src/org/simple/eventbus/handler/AsyncEventHandler.java +++ b/src/org/simple/eventbus/handler/AsyncEventHandler.java @@ -49,7 +49,7 @@ public AsyncEventHandler() { * @param subscription * @param event */ - public void handleEvent(final Subscription subscription, final Object event) { + public void handleEvent(final Subscription subscription, final Object... event) { mDispatcherThread.post(new Runnable() { @Override diff --git a/src/org/simple/eventbus/handler/DefaultEventHandler.java b/src/org/simple/eventbus/handler/DefaultEventHandler.java index 5c539a1..d791b9b 100644 --- a/src/org/simple/eventbus/handler/DefaultEventHandler.java +++ b/src/org/simple/eventbus/handler/DefaultEventHandler.java @@ -16,6 +16,7 @@ package org.simple.eventbus.handler; +import org.simple.eventbus.NULL; import org.simple.eventbus.Subscription; import java.lang.reflect.InvocationTargetException; @@ -32,13 +33,16 @@ public class DefaultEventHandler implements EventHandler { * @param subscription * @param event */ - public void handleEvent(Subscription subscription, Object event) { + public void handleEvent(Subscription subscription, Object... event) { if (subscription == null || subscription.subscriber.get() == null) { return; } try { // 执行 + if (event == null || event.length == 0 || (event.length == 1 && event[0] instanceof NULL)) { + event = null; + } subscription.targetMethod.invoke(subscription.subscriber.get(), event); } catch (IllegalArgumentException e) { e.printStackTrace(); diff --git a/src/org/simple/eventbus/handler/EventHandler.java b/src/org/simple/eventbus/handler/EventHandler.java index 5ff6c65..140c9a5 100644 --- a/src/org/simple/eventbus/handler/EventHandler.java +++ b/src/org/simple/eventbus/handler/EventHandler.java @@ -30,5 +30,5 @@ public interface EventHandler { * @param subscription 订阅对象 * @param event 待处理的事件 */ - void handleEvent(Subscription subscription, Object event); + void handleEvent(Subscription subscription, Object... event); } diff --git a/src/org/simple/eventbus/handler/UIThreadEventHandler.java b/src/org/simple/eventbus/handler/UIThreadEventHandler.java index 2cca10b..778ea45 100644 --- a/src/org/simple/eventbus/handler/UIThreadEventHandler.java +++ b/src/org/simple/eventbus/handler/UIThreadEventHandler.java @@ -41,7 +41,7 @@ public class UIThreadEventHandler implements EventHandler { * @param subscription * @param event */ - public void handleEvent(final Subscription subscription, final Object event) { + public void handleEvent(final Subscription subscription, final Object... event) { mUIHandler.post(new Runnable() { @Override diff --git a/src/org/simple/eventbus/matchpolicy/DefaultMatchPolicy.java b/src/org/simple/eventbus/matchpolicy/DefaultMatchPolicy.java index dd01f11..48272bf 100644 --- a/src/org/simple/eventbus/matchpolicy/DefaultMatchPolicy.java +++ b/src/org/simple/eventbus/matchpolicy/DefaultMatchPolicy.java @@ -25,6 +25,7 @@ package org.simple.eventbus.matchpolicy; import org.simple.eventbus.EventType; +import org.simple.eventbus.NULL; import java.util.LinkedList; import java.util.List; @@ -32,33 +33,43 @@ public class DefaultMatchPolicy implements MatchPolicy { @Override - public List findMatchEventTypes(EventType type, Object aEvent) { - Class eventClass = aEvent.getClass(); + public List findMatchEventTypes(EventType type, Object... aEvent) { List result = new LinkedList(); - while (eventClass != null) { - result.add(new EventType(eventClass, type.tag)); - addInterfaces(result, eventClass, type.tag); - eventClass = eventClass.getSuperclass(); + if (aEvent == null || aEvent.length == 0) { + Class[] eventClass = new Class[]{new NULL().getClass()}; + result.add(new EventType(type.tag, eventClass)); + } else { + Class[] eventClass = new Class[aEvent.length]; + for (int i = 0; i < aEvent.length; i++) { + Object o = aEvent[i]; + if (o == null) + o = new NULL(); + eventClass[i] = o.getClass(); + } +// while (eventClass != null) { + result.add(new EventType(type.tag, eventClass)); +// eventClass = addInterfaces(result, type.tag, eventClass); +// } } return result; } /** - * 获取该事件的所有接口类型 - * + * 获取该对象的所有接口类型 + * * @param eventTypes 存储列表 - * @param interfaces 事件实现的所有接口 + * @param eventClass 事件实现的所有接口 */ - private void addInterfaces(List eventTypes, Class eventClass, String tag) { + private void addInterface(List eventTypes, String tag, Class eventClass) { if (eventClass == null) { return; } Class[] interfacesClasses = eventClass.getInterfaces(); for (Class interfaceClass : interfacesClasses) { if (!eventTypes.contains(interfaceClass)) { - eventTypes.add(new EventType(interfaceClass, tag)); - addInterfaces(eventTypes, interfaceClass, tag); + eventTypes.add(new EventType(tag, interfaceClass)); + addInterface(eventTypes, tag, interfaceClass); } } } diff --git a/src/org/simple/eventbus/matchpolicy/MatchPolicy.java b/src/org/simple/eventbus/matchpolicy/MatchPolicy.java index 86f112b..3ab4471 100644 --- a/src/org/simple/eventbus/matchpolicy/MatchPolicy.java +++ b/src/org/simple/eventbus/matchpolicy/MatchPolicy.java @@ -32,5 +32,5 @@ * @author mrsimple */ public interface MatchPolicy { - List findMatchEventTypes(EventType type, Object aEvent); + List findMatchEventTypes(EventType type, Object... aEvent); } diff --git a/src/org/simple/eventbus/matchpolicy/StrictMatchPolicy.java b/src/org/simple/eventbus/matchpolicy/StrictMatchPolicy.java index 5e64279..fec306f 100644 --- a/src/org/simple/eventbus/matchpolicy/StrictMatchPolicy.java +++ b/src/org/simple/eventbus/matchpolicy/StrictMatchPolicy.java @@ -35,7 +35,7 @@ public class StrictMatchPolicy implements MatchPolicy { @Override - public List findMatchEventTypes(EventType type, Object aEvent) { + public List findMatchEventTypes(EventType type, Object... aEvent) { List result = new LinkedList(); result.add(type); return result; From d0273d0137ab3a675f43d644da658132e4aec431 Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 10 Dec 2015 16:07:45 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E8=AF=B4=E6=98=8E=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3e4d1d..dfcbc0d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,10 @@ This is an EventBus library for Android. It simplifies the communication between ## new feature -1. support sticky event; +1.对无参数方法的支持 +2.对多参数方法的支持 +3.sticky可以支持post过程 +4.事件post之后会被消耗 ## AndroidEventBus is adopted in the following app * [Accupass - Events around you](https://play.google.com/store/apps/details?id=com.accuvally.android.accupass) From e50a5643534b8a5d1b2e73051033cb0171f73587 Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 10 Dec 2015 16:45:22 +0800 Subject: [PATCH 3/7] =?UTF-8?q?androidstudio=E5=B7=A5=E7=A8=8B=E5=8F=98?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 6 ++++++ build.gradle | 46 ++++++++++++++++++++++++++++++++++++++++++++++ project.properties | 2 +- 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 build.gradle diff --git a/.gitignore b/.gitignore index 895aa13..8098e86 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,11 @@ gen/ # Gradle files .gradle/ build/ +.idea +*.iml +gradle/ +gradlew +gradlew.* # Local configuration file (sdk path, etc) local.properties @@ -34,3 +39,4 @@ proguard/ # Log Files *.log + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..38596db --- /dev/null +++ b/build.gradle @@ -0,0 +1,46 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:1.5.0' + } +} +apply plugin: 'com.android.library' + +dependencies { + compile fileTree(dir: 'libs', include: '*.jar') +} + +android { + compileSdkVersion 14 + buildToolsVersion "23.0.1" + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = ['src'] + resources.srcDirs = ['src'] + aidl.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + res.srcDirs = ['res'] + assets.srcDirs = ['assets'] + } + + // Move the tests to tests/java, tests/res, etc... + instrumentTest.setRoot('tests') + + // Move the build types to build-types/ + // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ... + // This moves them out of them default location under src//... which would + // conflict with src/ being used by the main source set. + // Adding new build types or product flavors should be accompanied + // by a similar customization. + debug.setRoot('build-types/debug') + release.setRoot('build-types/release') + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } +} diff --git a/project.properties b/project.properties index 03d0617..22e1c48 100644 --- a/project.properties +++ b/project.properties @@ -11,5 +11,5 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-10 +target=android-14 android.library=true From 31207b0421851622a790847abeda3407b91f1eb1 Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 21 Apr 2016 12:43:06 +0800 Subject: [PATCH 4/7] =?UTF-8?q?sticky=E7=9A=84=E5=A4=9A=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/simple/eventbus/EventBus.java | 3 ++- src/org/simple/eventbus/EventType.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/org/simple/eventbus/EventBus.java b/src/org/simple/eventbus/EventBus.java index 5079eed..2f57d35 100644 --- a/src/org/simple/eventbus/EventBus.java +++ b/src/org/simple/eventbus/EventBus.java @@ -238,6 +238,7 @@ public void postSticky(String tag, Object... event) { c[i] = o.getClass(); } EventType eventType = new EventType(tag, c); + eventType.event = event; mStickyEvents.add(eventType); mLocalEvents.get().offer(eventType); mDispatcher.dispatchEvents(event); @@ -479,7 +480,7 @@ void dispatchStickyEvents(Object subscriber) { private void handleStickyEvent(EventType eventType, Object subscriber) { List eventTypes = getMatchedEventTypes(eventType, eventType.event); // 事件 - Object event = eventType.event; + Object[] event = eventType.event; for (EventType foundEventType : eventTypes) { Log.e("", "### 找到的类型 : " + foundEventType.paramClass.toString() + ", event class : " + event.getClass().getSimpleName()); diff --git a/src/org/simple/eventbus/EventType.java b/src/org/simple/eventbus/EventType.java index 4203dd9..cd20fe6 100644 --- a/src/org/simple/eventbus/EventType.java +++ b/src/org/simple/eventbus/EventType.java @@ -34,7 +34,7 @@ public final class EventType { * 函数的tag */ public String tag = DEFAULT_TAG; - public Object event; + public Object[] event; /** * 参数类型 */ From 865c22f5eb83c9f9833512a58c8fa1d8802e3a58 Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 21 Apr 2016 14:42:26 +0800 Subject: [PATCH 5/7] =?UTF-8?q?sticky=E7=9A=84=E5=A4=9A=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/simple/eventbus/EventBus.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/simple/eventbus/EventBus.java b/src/org/simple/eventbus/EventBus.java index 2f57d35..fb6901b 100644 --- a/src/org/simple/eventbus/EventBus.java +++ b/src/org/simple/eventbus/EventBus.java @@ -80,7 +80,7 @@ public final class EventBus { * the thread local event queue, every single thread has it's own queue. */ ThreadLocal> mLocalEvents = new ThreadLocal>() { - protected java.util.Queue initialValue() { + protected Queue initialValue() { return new ConcurrentLinkedQueue(); } @@ -484,7 +484,7 @@ private void handleStickyEvent(EventType eventType, Object subscriber) { for (EventType foundEventType : eventTypes) { Log.e("", "### 找到的类型 : " + foundEventType.paramClass.toString() + ", event class : " + event.getClass().getSimpleName()); - final List subscriptions = mSubcriberMap.get(foundEventType); + final List subscriptions = loadMapKey(mSubcriberMap, foundEventType); if (subscriptions == null) { continue; } From 180f0d3dfcad910f51e53ec0139e5bc811be5b6c Mon Sep 17 00:00:00 2001 From: xujian Date: Thu, 21 Apr 2016 15:24:25 +0800 Subject: [PATCH 6/7] =?UTF-8?q?sticky=E7=9A=84=E5=A4=9A=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/simple/eventbus/EventBus.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/simple/eventbus/EventBus.java b/src/org/simple/eventbus/EventBus.java index fb6901b..48f3b0f 100644 --- a/src/org/simple/eventbus/EventBus.java +++ b/src/org/simple/eventbus/EventBus.java @@ -261,10 +261,10 @@ public void removeStickyEvent(String tag, Class... eventClass) { } else { Class[] c = new Class[eventClass.length]; for (int i = 0; i < eventClass.length; i++) { - Object o = eventClass[i]; + Class o = eventClass[i]; if (o == null) - o = new NULL(); - c[i] = o.getClass(); + o = new NULL().getClass(); + c[i] = o; } other = new EventType(tag, c); } From 1887098de4e9d75b40275402d6a0d5b951108139 Mon Sep 17 00:00:00 2001 From: xujian Date: Mon, 23 May 2016 09:58:15 +0800 Subject: [PATCH 7/7] =?UTF-8?q?sticky=E4=BA=8B=E4=BB=B6=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E4=BC=9A=E5=8E=BB=E9=87=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/org/simple/eventbus/EventBus.java | 40 ++++++++++++++++++++++----- src/org/simple/eventbus/NULL.java | 5 ++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/org/simple/eventbus/EventBus.java b/src/org/simple/eventbus/EventBus.java index 48f3b0f..d96b263 100644 --- a/src/org/simple/eventbus/EventBus.java +++ b/src/org/simple/eventbus/EventBus.java @@ -26,7 +26,6 @@ import org.simple.eventbus.matchpolicy.MatchPolicy; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; @@ -226,9 +225,11 @@ public void postSticky(String tag, Object... event) { if (event == null || event.length == 0) { EventType eventType = new EventType(tag, new NULL().getClass()); eventType.event = event; - mStickyEvents.add(eventType); - mLocalEvents.get().offer(eventType); - mDispatcher.dispatchEvents(event); + if (!checkStickyContains(eventType)) { + mStickyEvents.add(eventType); + mLocalEvents.get().offer(eventType); + mDispatcher.dispatchEvents(event); + } } else { Class[] c = new Class[event.length]; for (int i = 0; i < event.length; i++) { @@ -239,10 +240,35 @@ public void postSticky(String tag, Object... event) { } EventType eventType = new EventType(tag, c); eventType.event = event; - mStickyEvents.add(eventType); - mLocalEvents.get().offer(eventType); - mDispatcher.dispatchEvents(event); + if (!checkStickyContains(eventType)) { + mStickyEvents.add(eventType); + mLocalEvents.get().offer(eventType); + mDispatcher.dispatchEvents(event); + } + } + } + + private boolean checkStickyContains(EventType eventType) { + Iterator iterator = mStickyEvents.iterator(); + while (iterator.hasNext()) { + EventType mEventType = iterator.next(); + if (eventType.equals(mEventType)) { + if (mEventType.event == eventType.event) + return true; + else if (mEventType.event != null && eventType.event != null && mEventType.event.length == eventType.event.length) { + int all = 0; + for (int i = 0; i < mEventType.event.length; i++) { + if (mEventType.event[i].equals(eventType.event[i])) { + all++; + } + } + if (all == mEventType.event.length) { + return true; + } + } + } } + return false; } public void removeStickyEvent(Class... eventClass) { diff --git a/src/org/simple/eventbus/NULL.java b/src/org/simple/eventbus/NULL.java index 3bb8f7d..fc58340 100644 --- a/src/org/simple/eventbus/NULL.java +++ b/src/org/simple/eventbus/NULL.java @@ -9,4 +9,9 @@ public class NULL { public Object getValue() { return value; } + + @Override + public boolean equals(Object o) { + return getClass().equals(o.getClass()); + } }