【问题标题】:How to create an Observable in Android?如何在 Android 中创建 Observable?
【发布时间】:2016-03-07 16:51:01
【问题描述】:

我想做的是创建一个简单的内存缓存来尝试 Observables。但是我被卡住了,因为我不明白如何创建一个可观察的。这是我目前得到的代码:

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() 方法中,我想创建一个Observable 并将我的本地字段movieWrapper 返回给订阅者。我怎样才能做到这一点?我尝试使用new Observable.just(movieWrapper),但它会导致空异常。

【问题讨论】:

    标签: android rx-java rx-android


    【解决方案1】:

    看看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 而不是创建 时获得对象。

    但请注意,根据帖子作者的说法:

    defer() 唯一的缺点是它会创建一个新的 Observable 时间你得到一个订户。 create() 可以对每个函数使用相同的函数 订户,所以它更有效。与往常一样,衡量绩效和 必要时进行优化。

    【讨论】:

      【解决方案2】:

      如前所述,接受的答案有缺点

      每次获得订阅者时它都会创建一个新的 Observable

      但它不是唯一的。

      • 如果消费者在调用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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-06
        • 1970-01-01
        • 2014-10-16
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        • 2017-04-13
        相关资源
        最近更新 更多