Retrofit2+RxJava使用Flowable concat处理304响应的优化咨询
解决方案:使用
Single.empty()处理304状态码 你的核心需求是在Retrofit返回304时,既不触发订阅的accept回调(避免处理空对象),也不触发错误回调(保证后续Realm查询能正常执行),这个需求可以通过Single.empty()完美解决。
原理说明
Single.empty()是RxJava提供的一个特殊Single源:它不会发射任何数据,只会直接调用onComplete方法结束流。在Flowable.concat的逻辑中,当第一个流(Retrofit请求)正常完成后,会自动订阅并执行第二个流(Realm本地查询),完全不会影响后续逻辑。
相比你之前返回空对象的方案,这种方式不需要在consumer中做额外的空值判断,代码更简洁健壮。
修改后的代码实现
1. Retrofit响应处理部分
把304分支的返回值改成Single.empty():
return single.flatMap(new Function<Response<T1>, SingleSource<T1>>() { @Override public SingleSource<T1> apply(@NonNull Response<T1> response) throws Exception { if (response.code() == Integer.valueOf(ErrorUtils.CODE_200)) { return Single.just(response.body()); } else if (response.code() == Integer.valueOf(ErrorUtils.ERROR_CODE_304)) { // 304时不发射任何数据,直接完成流 return Single.empty(); } else { return Single.error(new Throwable(String.valueOf(response.code()))); } } });
2. 订阅回调部分
现在可以移除空对象判断,因为只有200状态码才会发射有效数据:
disposable.add(launchRequest() .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<Config>() { @Override public void accept(Config config) throws Exception { // 这里只会收到服务器返回的有效Config,无需空值判断 ProfileManager.getInstance().setConfig(config); } }, new Consumer<Throwable>() { @Override public void accept(@NonNull Throwable throwable) throws Exception { if (!throwable.getMessage().equals(ErrorUtils.ERROR_CODE_304)) { throwable.printStackTrace(); } } }));
注意事项
- 不要使用
Single.never()替代Single.empty():Single.never()不会触发onComplete,会导致Flowable.concat一直等待第一个流结束,永远不会执行后续的Realm查询。 - 确保Realm查询的流能正常发射数据:这样当304触发第一个流完成后,第二个流的有效数据会被
accept回调接收,完成本地数据的更新。
内容的提问来源于stack exchange,提问作者Vodet
相关产品推荐
相关产品推荐

