Reputation: 8106
since i would like to start my new app with a clean base im looking for a good way sharing Informations around different classes. For an example i would like to subscribe to an interface which may be used/shared by different classes.
Example for the interface/Observable way:
class SingleTonHolder {
private static _instance = null; // and initalize it using a static method.
private List<MyListener> myListeners new ArrayList<>();
public SingleTonHolder getInstance(){ return _instance }
public void registerListener(MyListener listener) { myListeners.add(listener); }
public void removeListener(MyListener listener) { myListeners.remove(listener); }
public void doSomethingToTheListener(...) { for(MyListener l : myListeners) l.doSomethingToTheListener(..); }
}
ClassOne extends MyListener {
public void onCreate() {
SingleTonHolder.getInstance().registerListener(this);
}
public vond onDestroy() {
SingleTonHolder.getInstance().removeListener(this);
}
}
and another class to listen for changes.
ClassTwo {
MyListener listener = null;
public void onCreate() {
listener = new MyListener( () => { .... });
SingleTonHolder.getInstance().registerListener(listener);
}
public vond onDestroy() {
SingleTonHolder.getInstance().removeListener(listener);
}
}
This does work and looks like the default solution. Everytime another Object calls SingleTonHolder.doSomethingToTheListener() it notify all registered listeners for changes.
Since i would like to try the same solution using RxJava2 and RxAndroid2 which lacks documentation i have tried the following way doing it.
Class CallFactory{
public Obvservable<List<Data>> getDummyData() { return anDummyObservable; }
}
Then ive created a Singleton Class which has a function to modify/observ onec a client subscribes.
public Observable<List<Data>> getData() {
return CallFactory.with(context)
.getDummyData(...)
.map(modifyList -> { /** do some processing **/return modifyList;
})
}
which doesnt work as excepted since every time a client subscribes it "recall" it and the client keeps connected until onCompleted() is called.
My first try to share the informations to all subscribed clients ive created a PublishSubject in my Singleton Class.
private PublishSubject<List<Data>> sharedSubject = PublishSubject.create();
Now i let my clients subscribe to the subjects using a method like
public PublishSubject getSharedSubject() { return this.sharedSubject; }
If i would like to send a Message which should be received by all listening clients then i have created something like
public void setNewData(List<Data> data) {
sharedSubject.onNext(data);
}
I am pretty sure that is not the way it should be, but is rxjava designed to serve such a solution? If i want to share events different then onNext, onError, onComplete, do i need to wrap an Interface in the onNext?
The codes are not tested and just to show how i understood it. Any help would be appreciate.
Upvotes: 3
Views: 2544
Reputation: 39836
Yes, RxJava used those 3 basic abstract callbacks onNext<T>
onComplete()
and onError()
.
But the important part that I believe you've missed is that, the Observer and Consumer are generic abstractions of an interface. Meaning you'll only have 3 callbacks, but you'll have 3 callbacks PER DATA TYPE.
The main idea on RxJava is to create the streams of data. Meaning you would have a PublishSubject<List<Data>>
, a PublishSubject<Foo>
, a PublishSubject<Bar>
, etc, etc. And then use one of the two interfaces Observer<T>
or Consumer<T>
. There's no need to create another interface or wrap it in something else. Just use the ones supplied by RxJava and put all the information you need inside the data.
I hope it helps.
Example:
// first class
public static class Foo implements Consumer<Data> {
Disposable d;
public Foo() {
this.d = SingleTonClass.subject.subscribe(this);
}
@Override void accept(Data data) {
.. here the original data
}
}
// second class
public static class Bar implements Consumer<MappedData> {
Disposable d;
public Foo() {
this.d = SingleTonClass.subject
.map( some data transform )
.subscribe(this);
}
@Override void accept(MappedData data) {
.. here the data after the map
}
}
class SingleTonClass {
public static PublishSubject<Data> subject = PublishSubject.create();
// then feel free to fire events in the subject:
public static void onSomethingHappen(){
subject.onNext(new Data(1));
}
public static void onOtherThingHappen(){
subject.onNext(new Data(2));
}
}
all in all, I wouldn't wrap the Rx calls into other things, but simply use them directly where needed.
Upvotes: 2