如何仅在onCreate调用一次代码,实现Retrofit返回值变化时自动通知
问题解答
你当前使用的普通@GET请求对应的Observable是冷流单次订阅,请求执行完成后流就自动终止,因此无法收到后续服务端的金币变动通知。你可以通过以下两种方案实现需求:
方案1:客户端轮询(无需后端修改,快速实现)
通过RxJava的interval操作符定时拉取金币数据,搭配distinctUntilChanged操作符过滤重复数据,即可实现仅初始化一次,后续金币变动自动收到通知的效果,修改后的代码如下:
// 首先声明Disposable成员变量,用于后续销毁订阅 private Disposable goldDisposable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 省略其他原有初始化逻辑 // 第一个参数0代表启动后立即执行第一次请求,第二个参数3代表轮询间隔3秒,可自行调整 goldDisposable = Observable.interval(0, 3, TimeUnit.SECONDS) .flatMap(tick -> Api.getClient1Or2().getGold("Admin") .subscribeOn(Schedulers.io())) // 仅当金币数值发生变化时才触发下游回调,过滤无变化的重复请求结果 .distinctUntilChanged() .observeOn(AndroidSchedulers.mainThread()) .subscribe( goldCount -> Log.d("GoldChange", "最新金币数量:" + goldCount), throwable -> Log.e("GoldError", "请求金币数据失败", throwable) ); } @Override protected void onDestroy() { super.onDestroy(); // 页面销毁时取消订阅,避免内存泄漏 if (goldDisposable != null && !goldDisposable.isDisposed()) { goldDisposable.dispose(); } }
注意事项
- 轮询间隔可根据业务对实时性的要求灵活调整,实时性要求越低,间隔可以设置越长,减少性能和流量消耗
- 如果拉取的金币返回是字符串格式,
distinctUntilChanged会默认对比字符串内容,不需要额外处理;如果后续改成数值类型,也可以正常对比
方案2:服务端主动推送(性能最优,无无效请求)
如果后端可以配合改造,建议采用WebSocket或者SSE(服务器发送事件)方案,服务端在金币数值发生变动时主动推送消息到客户端,不需要客户端定时发起无效请求。可以直接使用OkHttp的WebSocket能力搭配RxJava实现,无需大改动现有网络框架。
内容的提问来源于stack exchange,提问作者user21597761
相关产品推荐
相关产品推荐

