I\'m working on wrapping listeners into Observables. Normally we use Observable.create()
to wrap that but there are libraries prefer to use custom Observables a
Wherever possible I would use library provided creation methods like: generate
, fromCallable
or create
. There is no overhead in them. They take care of various housekeeping issues, which you can easily forget when writing your custom observable.
Unfortunately there are cases when you cannot use them, eg. when you need special scheduling. Before writing custom observable I would recommend looking into source code of generate
or create
library methods. Make sure you understand every bit of it, so you can do similar things in your observable.
Creating custom Observables offers lover overhead in some situations.
In RxJava 1.x, there is no benefit extending an Observable
and using Observable.create(OnSubscribe)
because they are practically the same. There is, however the benefit of creating an Observable
for an intermediate operator than using lift()
with a custom Operator
. Observable.create(Emitter, BackpressureStrategy)
adds overhead with the extra safeguard because people tend to find create
first and practically reimplement just()
, range()
or from()
with it before realizing it's unnecessary.
In RxJava 2.x, the default way is to extend Observable
and the other types to add source/intermediate operators which is the lowest overhead there could be. The safeguarded creation methods are still there but with some small investment into understanding the protocol, you can avoid the allocation of extra objects due to create()
by having an Observer
or Disposable
also implement the interfaces or extending a base class of the targeted external technology.
For example, this is how I wrote an adapter library for Java Swing and RxJava 2:
final class ActionEventObservable extends Observable<ActionEvent> {
final AbstractButton widget;
ActionEventObservable(AbstractButton widget) {
this.widget = widget;
}
@Override
protected void subscribeActual(Observer<? super ActionEvent> observer) {
AbstractButton w = widget;
ActionEventConsumer aec = new ActionEventConsumer(observer, w);
observer.onSubscribe(aec);
w.addActionListener(aec);
if (aec.get() == null) {
w.removeActionListener(aec);
}
}
static final class ActionEventConsumer
extends AbstractEventConsumer<ActionEvent, AbstractButton>
implements ActionListener {
private static final long serialVersionUID = -3605206827474016488L;
ActionEventConsumer(Observer<? super ActionEvent> actual, AbstractButton widget) {
super(actual, widget);
}
@Override
public void actionPerformed(ActionEvent e) {
actual.onNext(e);
}
@Override
protected void onDispose(AbstractButton component) {
component.removeActionListener(this);
}
}
}
Some Disposable management is hidden in a common AbstractEventConsumer
class and the individual event handlers mostly have to implement the required Listener
and call the appropriate remove method on dispose.
On a side note, most popular technologies may already have RxJava adapters you can use.