新用户登录后,BehaviorSubject会继续从旧的已注销用户发出用户数据吗?

时间:2018-01-23 01:17:43

标签: java android rx-java rx-java2

我目前正在使用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);
}

1 个答案:

答案 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);