1

I am new to Rx and I've been wondering how to properly emit values one by one (lazy load images in this example). What is the best way to do this without encountering concurrency issues?

This is my code:

@Override
public Observable<Bitmap> getPhotos(final String placeId) {
    return Observable.create(new ObservableOnSubscribe<Bitmap>() {
        @Override
        public void subscribe(ObservableEmitter<Bitmap> emitter) throws Exception {
            try {
                PlacePhotoMetadataResult res = Places.GeoDataApi
                        .getPlacePhotos(googleApiClient, placeId)
                        .await();
                PlacePhotoMetadataBuffer buffer = res.getPhotoMetadata();

                for (PlacePhotoMetadata photoMetadata : buffer) {
                    Bitmap photo = photoMetadata
                            .getPhoto(googleApiClient)
                            .await()
                            .getBitmap();

                    emitter.onNext(photo);
                }

                buffer.release();
            } catch (Exception ex) {
                emitter.onError(ex);
            } finally {
                emitter.onComplete();
            }
        }
    });
}

Thanks!

1
  • where is the loop here? Commented Feb 25, 2017 at 20:36

1 Answer 1

1

You really should invest some time in bridging PendingResult<T> to Observable<T> (or Single, or Flowable(my preference)). Then all your code can be expressed as:

private static <T> Observable<T> toObservable(PendingResult<T> result) {
    // 
}

public Observable<Bitmap> getPhotos(final String placeId) {
    return Observable
            .just(placeId)
            .flatMap(id -> toObservable(Places.GeoDataApi.getPlacePhotos(googleApiClient, placeId)))
            .flatMapIterable(PlacePhotoMetadataResult::getPhotoMetadata)
            .flatMap(metadata -> toObservable(metadata.getPhoto(googleApiClient)))
            .map(Photo::getBitmap);
}

A good place to start looking into how to do the bridge is this library, but it's RxJava 1 only.

Sign up to request clarification or add additional context in comments.

2 Comments

Is it fine to just return a Flowable instead of Observable and keep the rest of my code as it is? What backpressure strategy should I use?
Sure you can use Flowable, I just used Observable because that's what you use! And in this case you don't need to specify a backpressure strategy, the flatMapIterable will take care of it. You'll need to adapt toObservable tho.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.