How to create an Observable in Android?

What I want to do is create a simple cache in memory to try Observables. However, I am stuck because I don’t understand how to create an observable. This is the code I got so far:

public class MovieCache { MovieWrapper movieWrapper; public Observable<MovieWrapper> getMovies() { //How to create and return an Observable<MovieWrapper> here? } public void setCache(MovieWrapper wrapper) { movieWrapper = wrapper; } public void clearCache() { movieWrapper = null; } } 

In the getMovies() method, I want to create an Observable and return my local MovieWrapper file to the subscriber. How can i do this? I tried using new Observable.just(movieWrapper) , but this leads to a null exception.

+8
android rx-java rx-android
source share
2 answers

Take a look at this tutorial as it accurately accomplishes what you are looking for. Basically you use defer() to always get the latest version of your cached object:

 public class MovieCache { MovieWrapper movieWrapper; public Observable<MovieWrapper> getMovies() { return Observable.defer(new Func0<Observable<MovieWrapper>>() { @Override public Observable<MovieWrapper> call() { return Observable.just(movieWrapper); } }); } public void setCache(MovieWrapper wrapper) { movieWrapper = wrapper; } public void clearCache() { movieWrapper = null; } } 

defer() ensures that you get the object after subscribing to Observable not for creation.

Please note, however, that according to the author of the post:

The only drawback to defer () is that it creates a new observable every time you get a subscriber. create () can use the same function for each subscriber, therefore it is more efficient. As always, measure performance and optimize if necessary.

+6
source share

As already mentioned, the accepted answer has a drawback

it creates a new Observable every time you get a subscriber

But this is not the only one.

  • The consumer will not get any value if he calls getMovies().subscribe(...) before calling setCache(...) .
  • The consumer must unsubscribe if he wants to receive any updates (say, setCache() can be called several times.

Of course, all of them may be irrelevant in your scenario. I just want to show you another way (I'm sure there are many more). You can use BehaviorSubject to eliminate all of these shortcomings.

 public class MovieCache { private BehaviorSubject<MovieWrapper> mMovieCache = BehaviorSubject.create(); public void setCache(MovieWrapper wrapper) { mMovieCache.onNext(wrapper); } public Observable<MovieWrapper> getMovieObservable() { //use this if consumer want to receive all updates return mMovieCache.asObservable(); } public MovieWrapper getMovie() { //use this if consumer want to get only current value //and not interested in updates return mMovieCache.getValue(); } public void clearCache() { //CAUTION consumer should be ready to receive null value mMovieCache.onNext(null); //another way is to call mMovieCache.onCompleted(); //in this case consumer should be ready to resubcribe } public static class MovieWrapper {} } 

Take a look at the BehaviorSubject marble chart .

+3
source share

All Articles