Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava: How do I make a fetch-once-and-reuse Observable?

On every app launch, I have a Retrofit Observable that fetches the user's username from a server. I want to use this value for every subsequent subscriber, but it seems like every time I call subscribe(), the value is re-fetched from the network. Since the username isn't likely to change during the app's lifecycle, I'm not recreating the Observable object, only instantiating once.

How I want it to work is:

Create the Observable once

Fetch the username once, save that value in the Observable

On subscribe, use that saved value, or if it's not done fetching, wait for it to be fetched

How should I go about this?

like image 551
Steven Schoen Avatar asked Apr 24 '15 14:04

Steven Schoen


People also ask

How do you make an Observable in RxJava?

Following are the convenient methods to create observables in Observable class. just(T item) − Returns an Observable that signals the given (constant reference) item and then completes. fromIterable(Iterable source) − Converts an Iterable sequence into an ObservableSource that emits the items in the sequence.

Can we create our own Observable in RxJava?

RxJava provides many methods in its library to create an Observable. Choosing which one to use can be difficult. My goal from this article is to help you in making this choice simpler by providing you with a mental map of different scenarios and which methods to use in each scenario.

What is single observer in RxJava?

Single is an Observable that always emit only one value or throws an error. A typical use case of Single observable would be when we make a network call in Android and receive a response.

What is Completable RxJava?

Completable is only concerned with execution completion whether the task has reach to completion or some error has occurred. interface CompletableObserver<T> { void onSubscribe(Disposable d); void onComplete(); void onError(Throwable error);


2 Answers

You can use cache() which will retrieve the user name for the very first subscriber and will just replay the value to any subscribers then on (including the first of course).

like image 129
akarnokd Avatar answered Sep 29 '22 11:09

akarnokd


To elaborate on David's correct answer, here's some code that illustrates the use of cache:

public class Caching {
    public static void main(String[] args) throws IOException {
        Observable<String> observable = doSomethingExpensive().cache();
        observable.subscribe(System.out::println);
        observable.subscribe(System.out::println);
    }

    private static Observable<String> doSomethingExpensive(){
        return Observable.create(subscriber -> {
            System.out.println("Doing something expensive");
            subscriber.onNext("A result");
            subscriber.onCompleted();
        });
    }
}

Note that, even though you get results twice, you only do something expensive once.

like image 31
Rob Worsnop Avatar answered Sep 29 '22 10:09

Rob Worsnop