我想要做的是创建一个简单的内存缓存,只是为了尝试使用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异常。
答案 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 {}
}