如何在Android中创建Observable?

时间:2016-03-07 16:51:01

标签: android rx-java rx-android

我想要做的是创建一个简单的内存缓存,只是为了尝试使用Observables。但是我被卡住了,因为我不明白如何创建一个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()方法中,我想创建一个Observable并将我的本地字段movieWrapper返回给订阅者。我怎样才能做到这一点?我尝试使用new Observable.just(movieWrapper)但它会导致null异常。

2 个答案:

答案 0 :(得分:6)

看看this tutorial,因为它完全符合您的要求。基本上,您使用public class NoPaddingCardView extends CardView { public NoPaddingCardView(Context context) { super(context); init(); } public NoPaddingCardView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public NoPaddingCardView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { // Optional: Prevent pre-L from adding inner card padding setPreventCornerOverlap(false); // Optional: make Lollipop and above add shadow padding to match pre-L padding setUseCompatPadding(true); } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { // FIX shadow padding if (params instanceof MarginLayoutParams) { MarginLayoutParams layoutParams = (MarginLayoutParams) params; layoutParams.bottomMargin -= (getPaddingBottom() - getContentPaddingBottom()); layoutParams.leftMargin -= (getPaddingLeft() - getContentPaddingLeft()); layoutParams.rightMargin -= (getPaddingRight() - getContentPaddingRight()); layoutParams.topMargin -= (getPaddingTop() - getContentPaddingTop()); } super.setLayoutParams(params); } } 来确保始终获得最新版本的缓存对象:

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()而不是创建

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

  

defer()的唯一缺点是它每个都创建一个新的Observable   你得到订阅者的时间。 create()可以为每个使用相同的函数   订阅者,因此效率更高。一如既往,衡量绩效和   必要时进行优化。

答案 1 :(得分:3)

正如已经说过的,接受的答案有缺点

  

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

但它不是唯一的。

  • 如果在调用getMovies().subscribe(...)之前致电setCache(...),消费者将无法获得任何价值。
  • 如果消费者希望收到任何更新,请重新订阅(我们可以多次调用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