I’m working on networking for my app. So I decided to try out Square’s Retrofit. I see that they support simple Callback

@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);

and RxJava’s Observable

@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);

Both look pretty similar at first glance, but when it gets to implementation it gets interesting…

While with simple callback implementation would look similar to this:

api.getUserPhoto(photoId, new Callback<Photo>() {
    @Override
    public void onSuccess() {
    }
});

which is quite simple and straightforward. And with Observable it quickly gets verbose and quite complicated.

public Observable<Photo> getUserPhoto(final int photoId) {
    return Observable.create(new Observable.OnSubscribeFunc<Photo>() {
        @Override
        public Subscription onSubscribe(Observer<? super Photo> observer) {
            try {
                observer.onNext(api.getUserPhoto(photoId));
                observer.onCompleted();
            } catch (Exception e) {
                observer.onError(e);
            }

            return Subscriptions.empty();
        }
    }).subscribeOn(Schedulers.threadPoolForIO());
}

And that is not it. You still have to do something like this:

Observable.from(photoIdArray)
        .mapMany(new Func1<String, Observable<Photo>>() {
            @Override
            public Observable<Photo> call(Integer s) {
                return getUserPhoto(s);
            }
        })
        .subscribeOn(Schedulers.threadPoolForIO())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Photo>() {
            @Override
            public void call(Photo photo) {
                //save photo?
            }
        });

Am I missing something here? Or is this a wrong case to use Observables?
When would/should one prefer Observable over simple Callback?

Update

Using retrofit is much simpler than example above as @Niels showed in his answer or in Jake Wharton’s example project U2020. But essentially the question stays the same – when should one use one way or the other?

9 Answers
9

Leave a Reply

Your email address will not be published. Required fields are marked *