2016-03-07 18 views
8

Quello che voglio fare è creare una semplice cache in memoria solo per provare Observables out. Tuttavia mi sono bloccato perché non capisco come creare un osservabile. Questo è il codice che ho ottenuto finora:Come creare un Observable in Android?

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; 
    } 
} 

Nel metodo getMovies() voglio creare un osservabile e restituire il mio movieWrapper campo locale al sottoscrittore. Come posso fare questo? Ho provato con l'uso di new Observable.just(movieWrapper) ma risulta in un'eccezione nulla.

risposta

6

Dai uno sguardo allo this tutorial perché fa esattamente quello che stai cercando. In pratica si utilizza defer() per essere sicuri di ottenere sempre l'ultima versione del vostro oggetto in cache:

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() fa in modo che si otterrà l'oggetto su abbonamento alla Observable non sulla creazione .

nota, tuttavia, che, secondo l'autore del post:

L'unico lato negativo di rinviare() è che si crea un nuovo osservabile ogni volta che si ottiene un abbonato. create() può utilizzare la stessa funzione per ogni utente , quindi è più efficiente. Come sempre, misurare le prestazioni e ottimizzare se necessario.

+1

ho provato questo e funziona benissimo, grazie mille! –

3

Come già detto, risposta accettata ha ribasso

crea un nuovo osservabile ogni volta che si ottiene un abbonato

Ma non è l'unico.

  • consumatori non riceverà alcun valore se lui chiama getMovies().subscribe(...) prima setCache(...) si chiama.
  • consumatori dovrebbe sottoscrivere nuovamente se vuole ricevere eventuali aggiornamenti (diciamo setCache() può essere chiamato più volte.

Naturalmente tutti possono essere irrilevante nello scenario. Voglio solo mostrarvi un altro modo (sono sicuro che ci sono molti di più). È possibile utilizzare BehaviorSubject al fine di eliminare tutti questi inconvenienti.

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 {} 

} 

Date un'occhiata a BehaviorSubject marble diagram.

Problemi correlati