2016-03-07 16 views
8

Was ich tun möchte, ist einen einfachen In-Memory-Cache zu erstellen, nur um Observables auszuprobieren. Ich bin jedoch steckengeblieben, weil ich nicht verstehe, wie man ein Observable erstellt. Dies ist der Code, den ich bisher bekommen haben:Wie erstelle ich ein 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; 
    } 
} 

Im getMovies() Methode Ich möchte einen beobachtbaren schaffen und meine lokalen Feld movieWrapper an den Teilnehmer zurück. Wie kann ich das machen? Ich habe versucht mit new Observable.just(movieWrapper), aber es führt zu einer Null-Ausnahme.

Antwort

6

Werfen Sie einen Blick auf this tutorial, da es genau das tut, was Sie suchen. Grundsätzlich Sie defer() verwenden, um sicherzustellen, dass Sie immer die neueste Version Ihres Cache gespeicherten Objekt erhalten:

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() stellt sicher, dass Sie das Objekt auf Abonnement zum Observable nicht auf Schöpfung zu bekommen.

ist jedoch zu beachten, dass nach dem Autor des Posts:

Der einzige Nachteil zu verschieben() ist, dass es ein neues Observable jedes Mal, wenn Sie einen Teilnehmer erhalten erstellt. create() kann dieselbe Funktion für jeden Abonnenten verwenden, also ist es effizienter. Wie immer, messen Sie die Leistung und optimieren Sie bei Bedarf.

+1

ich habe versucht, Das und es funktioniert super, vielen Dank! –

3

Wie bereits gesagt, hat akzeptierte Antwort

es schafft eine neue Observable jedes Mal, wenn ein Teilnehmer

Aber es ist nicht der einzige bekommen Nachteil.

  • Consumer wird keinen Wert erhalten, wenn er ruft getMovies().subscribe(...) vor setCache(...) genannt wird.
  • Verbraucher sollten resubscribe wenn er keine Updates erhalten möchten (sagen wir mal setCache() mehrmals aufgerufen werden kann.

Natürlich alle von ihnen in Ihrem Szenario irrelevant sein kann. Ich möchte Ihnen eine andere Art und Weise zeigen, (ich bin sicher, es gibt viele mehr). Sie BehaviorSubject, um alle diese Nachteile zu beseitigen können.

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

} 

Werfen Sie einen Blick auf BehaviorSubject marble diagram.

Verwandte Themen