2016-06-15 29 views
1

Ist es in Otto möglich, Ereignisse zu abonnieren, ohne @Subscribe Annotation zu verwenden?Otto Event Bus Runtime-Abonnement für Ereignisse

In meinem Anwendungsfall weiß ich nicht, zu welchem ​​Ereignis mein Objekt zur Kompilierzeit abonnieren sollte. Ich möchte es zur Laufzeit nach bestimmten Regeln machen.

+0

Vielleicht tun Sie es mit anderen Objekttypen –

+0

Es ist nicht möglich. https://github.com/square/otto/blob/a85ae721d337d9129eb49f5dc90c8e65d49d48ca/otto/src/main/java/com/squarepeup/otto/AnnotatedHandlerFinder.java#L72 – Ozgur

+0

@SimonMarquis können Sie bitte erklären? –

Antwort

2

Ich nehme an, Sie eine Abhilfe wie diese verwenden können,

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 { 
} 

Eine andere Lösung, die eine viel sauberere Lösung. Sie können das Ereignis zur Laufzeit mit dem gewünschten Typ generieren.

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; 
    } 
} 
0

Ich habe ein Framework für das Abonnieren von Ereignissen in Runtime mit Otto erstellt. Anstatt verschiedene Model-Klassen für verschiedene Event-Typen zu haben, kann man verschiedene EventDelegate für verschiedene Events haben. Diese Ereignisdelegierten empfangen und senden nur Ereignisse und leiten sie an Teilnehmerklassen weiter. Eine typische EventDelegate aussehen wird dieses

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; 
} 
} 

Dieser Ansatz in this article erläutert. Auch wenn Sie sich die Implementierung ansehen möchten. Es ist auf Github here.