diff --git a/EventBus/src/org/greenrobot/eventbus/EventBus.java b/EventBus/src/org/greenrobot/eventbus/EventBus.java index 147bb5ff..7a3729f6 100644 --- a/EventBus/src/org/greenrobot/eventbus/EventBus.java +++ b/EventBus/src/org/greenrobot/eventbus/EventBus.java @@ -15,6 +15,8 @@ */ package org.greenrobot.eventbus; +import android.util.Log; + import org.greenrobot.eventbus.android.AndroidDependenciesDetector; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -140,6 +142,10 @@ public EventBus() { * ThreadMode} and priority. */ public void register(Object subscriber) { + register(subscriber, null); + } + + public void register(Object subscriber, Object id) { if (AndroidDependenciesDetector.isAndroidSDKAvailable() && !AndroidDependenciesDetector.areAndroidComponentsAvailable()) { // Crash if the user (developer) has not imported the Android compatibility library. throw new RuntimeException("It looks like you are using EventBus on Android, " + @@ -150,15 +156,15 @@ public void register(Object subscriber) { List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { - subscribe(subscriber, subscriberMethod); + subscribe(id, subscriber, subscriberMethod); } } } // Must be called in synchronized block - private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) { + private void subscribe(Object id, Object subscriber, SubscriberMethod subscriberMethod) { Class eventType = subscriberMethod.eventType; - Subscription newSubscription = new Subscription(subscriber, subscriberMethod); + Subscription newSubscription = new Subscription(id, subscriber, subscriberMethod); CopyOnWriteArrayList subscriptions = subscriptionsByEventType.get(eventType); if (subscriptions == null) { subscriptions = new CopyOnWriteArrayList<>(); @@ -260,6 +266,10 @@ public synchronized void unregister(Object subscriber) { /** Posts the given event to the event bus. */ public void post(Object event) { + post(event, null); + } + + public void post(Object event, Object id) { PostingThreadState postingState = currentPostingThreadState.get(); List eventQueue = postingState.eventQueue; eventQueue.add(event); @@ -272,7 +282,7 @@ public void post(Object event) { } try { while (!eventQueue.isEmpty()) { - postSingleEvent(eventQueue.remove(0), postingState); + postSingleEvent(id, eventQueue.remove(0), postingState); } } finally { postingState.isPosting = false; @@ -309,11 +319,15 @@ public void cancelEventDelivery(Object event) { * event of an event's type is kept in memory for future access by subscribers using {@link Subscribe#sticky()}. */ public void postSticky(Object event) { + postSticky(event, null); + } + + public void postSticky(Object event, Object id) { synchronized (stickyEvents) { stickyEvents.put(event.getClass(), event); } // Should be posted after it is putted, in case the subscriber wants to remove immediately - post(event); + post(event, id); } /** @@ -383,7 +397,7 @@ public boolean hasSubscriberForEvent(Class eventClass) { return false; } - private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { + private void postSingleEvent(Object id, Object event, PostingThreadState postingState) throws Error { Class eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) { @@ -391,10 +405,10 @@ private void postSingleEvent(Object event, PostingThreadState postingState) thro int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class clazz = eventTypes.get(h); - subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); + subscriptionFound |= postSingleEventForEventType(id, event, postingState, clazz); } } else { - subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); + subscriptionFound = postSingleEventForEventType(id, event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { @@ -407,12 +421,13 @@ private void postSingleEvent(Object event, PostingThreadState postingState) thro } } - private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class eventClass) { + private boolean postSingleEventForEventType(Object id, Object event, PostingThreadState postingState, Class eventClass) { CopyOnWriteArrayList subscriptions; synchronized (this) { subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { + subscriptions = clearSubscriptionsById(subscriptions, id); for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; @@ -434,6 +449,20 @@ private boolean postSingleEventForEventType(Object event, PostingThreadState pos return false; } + private CopyOnWriteArrayList clearSubscriptionsById(CopyOnWriteArrayList subscriptions, Object id) { + if (id == null){ + return subscriptions; + } else { + CopyOnWriteArrayList result = new CopyOnWriteArrayList<>(); + for (Subscription s : subscriptions) { + if (s.id == id) { + result.add(s); + } + } + return result; + } + } + private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case POSTING: diff --git a/EventBus/src/org/greenrobot/eventbus/Subscription.java b/EventBus/src/org/greenrobot/eventbus/Subscription.java index cc0de1e3..0c94c1ef 100644 --- a/EventBus/src/org/greenrobot/eventbus/Subscription.java +++ b/EventBus/src/org/greenrobot/eventbus/Subscription.java @@ -16,6 +16,7 @@ package org.greenrobot.eventbus; final class Subscription { + final Object id; final Object subscriber; final SubscriberMethod subscriberMethod; /** @@ -24,7 +25,8 @@ final class Subscription { */ volatile boolean active; - Subscription(Object subscriber, SubscriberMethod subscriberMethod) { + Subscription(Object id, Object subscriber, SubscriberMethod subscriberMethod) { + this.id = id; this.subscriber = subscriber; this.subscriberMethod = subscriberMethod; active = true; diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusPostByIdTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusPostByIdTest.java new file mode 100644 index 00000000..66b58f2a --- /dev/null +++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusPostByIdTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.greenrobot.eventbus; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * @author Emir Rahman Muhammadzadeh + */ +public class EventBusPostByIdTest extends AbstractAndroidEventBusTest { + @Test + public void testPostById() throws InterruptedException { + + Object obj1 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello First Object", event); + } + }; + + Object obj2 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello Second Object", event); + } + }; + + Object obj3 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello Third Object", event); + } + }; + + eventBus.register(obj1, 1); + eventBus.register(obj2, 2); + eventBus.register(obj3, 3); + + + eventBus.post("hello First Object", 1); + eventBus.post("hello Second Object", 2); + eventBus.post("hello Third Object", 3); + } + + @Test + public void testPostPublic() throws InterruptedException { + + Object obj1 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello everybody", event); + } + }; + + Object obj2 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello everybody", event); + } + }; + + Object obj3 = new Object() { + @Subscribe(threadMode = ThreadMode.MAIN) + public void onEvent(String event) { + assertEquals("hello everybody", event); + } + }; + + eventBus.register(obj1, 1); + eventBus.register(obj2, 2); + eventBus.register(obj3, 3); + + eventBus.post("hello everybody"); + + } + +}