diff --git a/EventBus/src/org/greenrobot/eventbus/EventBus.java b/EventBus/src/org/greenrobot/eventbus/EventBus.java index 1cd57e32..799518d7 100644 --- a/EventBus/src/org/greenrobot/eventbus/EventBus.java +++ b/EventBus/src/org/greenrobot/eventbus/EventBus.java @@ -31,10 +31,10 @@ /** * EventBus is a central publish/subscribe event system for Android. Events are posted ({@link #post(Object)}) to the * bus, which delivers it to subscribers that have a matching handler method for the event type. To receive events, - * subscribers must register themselves to the bus using {@link #register(Object)}. Once registered, subscribers - * receive events until {@link #unregister(Object)} is called. Event handling methods must be annotated by - * {@link Subscribe}, must be public, return nothing (void), and have exactly one parameter - * (the event). + * subscribers must register themselves to the bus using {@link #register(Object)} or {@link #register(Object, Class)}. + * Once registered, subscribers receive events until {@link #unregister(Object)} or {@link #unregister(Object, Class)} + * is called. Event handling methods must be annotated by {@link Subscribe}, must be public, return nothing (void), + * and have exactly one parameter (the event). * * @author Markus Junginger, greenrobot */ @@ -123,20 +123,31 @@ public EventBus() { executorService = builder.executorService; } + /** Registers the given subscriber to receive events. + * See more information in {@link #register(Object, Class)}. + */ + public void register(Object subscriber) { + register(subscriber, null); + } + + /** - * Registers the given subscriber to receive events. Subscribers must call {@link #unregister(Object)} once they - * are no longer interested in receiving events. + * Registers the given subscriber to receive the event specified or all if none specified. + * Subscribers must call {@link #unregister(Object, Class)} once they are + * no longer interested in receiving events. *

* Subscribers have event handling methods that must be annotated by {@link Subscribe}. * The {@link Subscribe} annotation also allows configuration like {@link * ThreadMode} and priority. */ - public void register(Object subscriber) { + public void register(Object subscriber, Class eventType) { Class subscriberClass = subscriber.getClass(); List subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass); synchronized (this) { for (SubscriberMethod subscriberMethod : subscriberMethods) { - subscribe(subscriber, subscriberMethod); + if (eventType == null || eventType.equals(subscriberMethod.eventType)) { + subscribe(subscriber, subscriberMethod); + } } } } @@ -223,12 +234,29 @@ private void unsubscribeByEventType(Object subscriber, Class eventType) { /** Unregisters the given subscriber from all event classes. */ public synchronized void unregister(Object subscriber) { - List> subscribedTypes = typesBySubscriber.get(subscriber); - if (subscribedTypes != null) { - for (Class eventType : subscribedTypes) { - unsubscribeByEventType(subscriber, eventType); + unregister(unsubscriber, null); + } + + /** Unregisters the given subscriber from the event class specified, or all events if none specified. */ + public synchronized void unregister(Object subscriber, Class eventType) { + List> typesToUnsubscribe = subscribedTypes != null ? new ArrayList<>(subscribedTypes) : null; + if (eventType != null) { + if (typesToUnsubscribe != null && typesToUnsubscribe.contains(eventType)) { + typesToUnsubscribe.clear(); + typesToUnsubscribe.add(eventType); + } else { + Log.w(TAG, "Subscriber " + subscriber.getClass() + " was not registered before for event: " + eventType); + return; + } + } + if (typesToUnsubscribe != null) { + for (Class subscribedType : typesToUnsubscribe) { + unsubscribeByEventType(subscriber, subscribedType); + subscribedTypes.remove(subscribedType); + } + if (subscribedTypes.isEmpty()) { + typesBySubscriber.remove(subscriber); } - typesBySubscriber.remove(subscriber); } else { Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass()); } diff --git a/EventBusTest/src/org/greenrobot/eventbus/OneEventRegisteringTest.java b/EventBusTest/src/org/greenrobot/eventbus/OneEventRegisteringTest.java new file mode 100644 index 00000000..4f20286c --- /dev/null +++ b/EventBusTest/src/org/greenrobot/eventbus/OneEventRegisteringTest.java @@ -0,0 +1,29 @@ +package org.greenrobot.eventbus; + +import org.junit.Test; + +/** + * Created by driesgo on 15/09/17. + */ + +public class OneEventRegisteringTest extends AbstractEventBusTest { + + @Test + public void testRegisterForOneEvent() { + eventBus.register(this, String.class); + eventBus.post("Foo"); + eventBus.post(new IntTestEvent(1)); + assertEventCount(1); + } + + @Subscribe + public void onEvent(String event) { + trackEvent(event); + } + + @Subscribe + public void onEvent(IntTestEvent event) { + trackEvent(event); + } + +} diff --git a/EventBusTest/src/org/greenrobot/eventbus/OneEventUnregisteringTest.java b/EventBusTest/src/org/greenrobot/eventbus/OneEventUnregisteringTest.java new file mode 100644 index 00000000..284a3ed5 --- /dev/null +++ b/EventBusTest/src/org/greenrobot/eventbus/OneEventUnregisteringTest.java @@ -0,0 +1,34 @@ +package org.greenrobot.eventbus; + +import org.junit.Test; + +/** + * Created by driesgo on 15/09/17. + */ + +public class OneEventUnregisteringTest extends AbstractEventBusTest { + + @Test + public void testUnregisterForOneEvent() { + eventBus.register(this); + eventBus.post("Foo"); + eventBus.post(new IntTestEvent(1)); + assertEventCount(2); + eventBus.unregister(this, String.class); + eventBus.post("Bar"); + assertEventCount(2); + eventBus.post(new IntTestEvent(1)); + assertEventCount(3); + } + + @Subscribe + public void onEvent(String event) { + trackEvent(event); + } + + @Subscribe + public void onEvent(IntTestEvent event) { + trackEvent(event); + } + +}