1

Is it possible in Otto to subscribe to events without using @Subscribe annotation ?

In my use case I do not know to which event my object should subscribe to at compile time. I wish to do it at runtime based on certain rules.

Abhishek Bansal
  • 5,197
  • 4
  • 40
  • 69

2 Answers2

2

I suppose you can use a workaround like this,

public class MainClass {    

    private EventObserver eventObserver;

    public MainClass() {
        if(...someCondition...) {
            eventObserver = new FirstEventObserver();
        } else {
            eventObserver = new SecondEventObserver();
        }
    }

    public onEvent(Event event) {
        if (event instanceOf FirstEvent) {
            ... handle event ...
        } else if (event instanceOf SecondEvent) {
            ... handle event ...
        }
    }
}

public abstract class EventObserver {

    protected MainClass mainClass;

    public void setMainClass(MainClass mainClass) {
        this.mainClass = mainClass;
    }

    protected void notifyMainClass(Event event) {
        if (mainClass != null) {
            mainClass.onEvent(event);
        }
    }
}

public class FirstEventObserver extends EventObserver {

    public FirstEventObserver() {
        bus.subscribe(this);
    }

    @Subscribe
    public void onEvent(FirstEvent event) {
        notifyMainClass();
    }
}


public class SecondEventObserver extends EventObserver {

    public SecondEventObserver() {
        bus.subscribe(this);
    }

    @Subscribe
    public void onEvent(SecondEvent event) {
        notifyMainClass();
    }
}

public abstract class Event {
}

public abstract class FirstEvent extends Event {
}

public abstract class SecondEvent extends Event {
}

Another workaround, which is a much cleaner solution. You can generate the event at runtime with the type you want.

public class MainClass {
    @Subscribe
    public void onEvent(Event event) {
        if (event.getType() == EventType.FIRST_EVENT) {
            ... handle event ...
        } else if (event.getType() == EventType.SECOND_EVENT) {
            ... handle event ...
        }
    }
}

public class Event {
    public enum EventType {
        FIRST_EVENT,
        SECOND_EVENT
    }

    private EventType eventType;

    public Event(EventType eventType) {
        this.eventType = eventType;
    }

    public EventType getType() {
        return eventType;
    }
}
Anuj
  • 1,912
  • 1
  • 12
  • 19
0

I created a framework for subscribing to events in runtime with Otto. Instead of having different Model classes for different event types one can have different EventDelegate for different events. These event delegate will just receive and event and pass them on to subscriber classes. A Typical EventDelegate will look like this

public abstract class OttoEventDelegate {
private OttoEventListener ottoEventListener;

public OttoEventDelegate(OttoEventListener ottoEventListener) {
    this.ottoEventListener = ottoEventListener;
}

public void register() {
    BaseApplication.getInstance().getBus().register(this);
}

public void unregister() {
    BaseApplication.getInstance().getBus().unregister(this);
}

public OttoEventListener getOttoEventListener() {
    return ottoEventListener;
}

public void setOttoEventListener(OttoEventListener ottoEventListener) {
    this.ottoEventListener = ottoEventListener;
}
}

This Approach is explained in this article. Also if you want to have a look at implementation. Its on github here.

Abhishek Bansal
  • 5,197
  • 4
  • 40
  • 69