How I would refactor your code; alongside getData method, I would add the getData method wrapped as a Single:
public void getData( final OnResponseListener listener ){
if(data!=null && !data.isEmpty()){
listener.onSuccess();
}
else{
listener.onError();
}
}
public Single<Boolean> getDataSingle() {
return Single.create(new SingleOnSubscribe<Boolean>() {
@Override
public void subscribe(SingleEmitter<Boolean> e) throws Exception {
getData(new OnResponseListener() {
@Override
public void onSuccess() {
e.onSuccess(true);
}
@Override
public void onError() {
e.onSuccess(false);
}
});
}
});
}
Or with Java 8 :
public Single<Boolean> getDataSingle() {
return Single.create(e -> getData(
new OnResponseListener() {
@Override
public void onSuccess() {
e.onSuccess(true);
}
@Override
public void onError() {
e.onSuccess(false);
}
})
);
}
Now you have exposed a Rx API alongside the callback's one. Supposing it's some kind of DataProvider of your own, you can now use it without dealing with callbacks, like this:
dataProvider.getDataSingle()
.map(result -> result ? "User exist" : "User doesn't exist")
.subscribe(message -> display(message));
I used Rx2 but with Rx1 the logic is the same.
I also used a Single instead of an Observable, since you await only one value. The interest is a more expressive contract for your function.
You can't emit value on behalf of an Observable, ie calling something like myObservable.send(value). The first solution is to use a Subject. Another solution (the one above) is to create the observable with Observable.create() (or Single.create()). You call the callback method and create the listener inside the method Observable.create(), because it's inside Observable.create() that you can call onSuccess() method, the method who told the Observable to pass down a value.
It's what I use to wrap callback into observable. A bit complicated at first, but easy to adapt.
I give you another example, as asked. Let's say you want to display the changes of an EditText as a Snackbar:
View rootView;
EditText editTextView;
//Wrap Android addTextChangedListener into an Observable
Observable<String> textObservable = Observable.create(consumer ->
editTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
consumer.onNext(s.toString());
}
})
);
//Use it
textObservable.subscribe(text -> Snackbar.make(rootView, text, Snackbar.LENGTH_SHORT).show());