Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature proposal: Partial registering and unregistering #471

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 41 additions & 13 deletions EventBus/src/org/greenrobot/eventbus/EventBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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.
* <p/>
* 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<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
if (eventType == null || eventType.equals(subscriberMethod.eventType)) {
subscribe(subscriber, subscriberMethod);
}
}
}
}
Expand Down Expand Up @@ -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<Class<?>> 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<Class<?>> 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());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
@@ -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);
}

}