2016-03-07 61 views
8

我想要做的是创建一个简单的内存中缓存,只是为了试用Observables。但是我被卡住了,因为我不明白如何创建一个observable。这是迄今为止我已经得到的代码:如何在Android中创建Observable?

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

getMovies()方法我想创建一个可观察和我的本地视野movieWrapper返回给用户。我怎样才能做到这一点?我尝试使用new Observable.just(movieWrapper),但它导致空例外。

回答

6

看看this tutorial,因为它确实如你所想。基本上你使用defer(),以确保您始终获得您的高速缓存对象的最新版本:

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()可以确保您将在订阅获取对象的Observable创作

然而要注意,根据帖子的作者:

唯一的缺点推迟()是它创建了一个新的可观察每个 时候你得到一个用户。 create()可以为每个订户使用相同的功能,因此效率更高。一如既往,衡量性能,并在必要时进行优化。

+1

我试着这和它很好,非常感谢! –

3

前面已经说了,接受的答案有下行

它创建你得到一个用户

一个新的可观察每次但它不是唯一的一个。

  • 如果在调用setCache(...)之前拨打getMovies().subscribe(...),消费者将不会收到任何价值。
  • 消费者应该重新订阅,如果他想接收任何更新(假设setCache()可以多次调用。

当然,所有这些都可以在您的方案无关,我只是想告诉你另一种方式(我敢肯定还有更多)。 可以以消除所有这些缺点使用BehaviorSubject

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

} 

看看BehaviorSubject marble diagram