我目前正在使用BehaviorSubject(RxJava)来缓存来自API的结果,因此后续加载速度要快得多。然而,这很好用,直到我退出我的应用程序。一旦我注销然后以其他用户身份重新登录,由于某种原因,尽管请求来自不同的用户ID,但响应与旧用户ID相同。即使我再次退出并重新登录,它仍然是这种方式。它仅在我关闭应用程序时重置,并在屏幕上重新打开时,响应数据会更改为当前用户。
我将问题缩小到行为主题。有没有办法,在退出应用程序时(或在应用程序中登录之前),删除所有BehaviorSubjects?如果用户之前已经登录,我允许应用程序自动定向到主页面,这不是问题,只有当用户登录新的时才会删除BehaviorSubject。
我的想法是将一个hashmap存储在某个地方,将键映射到BehaviorSubjects。一旦我退出,我就清除了这个hashmap(这样我可以清除我应用程序中的所有BehaviorSubjects,而不仅仅是这个)。
Disposable disposable = getData(
request,
(List<Item> items) -> {
RecyclerView.Adapter adapter = mBinding.recyclerView.getAdapter();
if (adapter instanceof ItemAdapter) {
((ItemAdapter) adapter).setItems(items);
} else {
adapter = ItemAdapter.getInstance(items);
mBinding.recyclerView.setAdapter(adapter);
}
},
(Throwable ex) -> {
Log.e(TAG, ex.getMessage());
});
以下是其他代码:
public Disposable getData(SomeRequest request, Consumer<List<Item>> onNext, Consumer<Throwable> onError) {
BehaviorSubject cacheSubject = getCache("Key"); // get BehaviorSubject stored earlier
if (cacheSubject == null) {
BehaviorSubject<List<Item>> cache = BehaviorSubject.create();
Observable.create((ObservableEmitter<List<Item>> e) -> {
getApi().getQuery(request)
.subscribeOn(Schedulers.io())
.subscribe((Response<ResponseBody> response) -> {
if (response.body() != null) {
ResponseBody body = response.body();
if (body.getItems() != null) {
List<Item> items = body.getItems();
cache.onNext(items);
}
}
}, (Throwable ex) -> {
Log.e(TAG, ex.getMessage());
cache.onError(ex);
});
})
.subscribeOn(Schedulers.io())
.subscribe(cache);
putCache("Key", cache); // update or create new BehaviorSubject in that map
cacheSubject = cache;
}
return cacheSubject
.observeOn(AndroidSchedulers.mainThread())
.subscribe(onNext, onError);
}
答案 0 :(得分:0)
我假设您要清除BehaviorSubject(因为否则不会在其上调用onComplete)。这是不受支持的,但你可以通过消费者忽略的当前值来实现类似的效果:
public static final Object EMPTY = new Object();
BehaviorSubject<Object> subject = BehaviorSubject.createDefault(EMPTY);
Observable<YourType> obs = subject.filter(v -> v != EMTPY).cast(YourType.class);
obs.subscribe(System.out::println);
// send normal data
subject.onNext(1);
subject.onNext(2);
// clear the subject
subject.onNext(EMPTY);
// this should not print anything
obs.subscribe(System.out::println);