使用RxJava repeatUntil轮询请求报错:需BooleanSupplier而非Unit
解决RxJava repeatUntil操作符的错误问题
你遇到的问题核心是对repeatUntil的工作机制理解有误,另外线程调度的顺序也写反了,我来一步步帮你修正:
错误原因解析
repeatUntil的参数要求:它需要的是一个BooleanSupplier(无参函数,返回boolean值),而不是手动调用onComplete()。当这个函数返回true时,轮询会停止;返回false时,会重新订阅上游的Observable,继续执行请求。- 线程调度顺序错误:你把
subscribeOn和observeOn搞反了——subscribeOn应该指定上游网络请求执行的线程(比如Schedulers.io()),observeOn指定**下游回调(更新UI等)**的线程(AndroidSchedulers.mainThread())。
修正后的代码
// 定义变量保存请求成功状态 var isSignUpReady = false accountDelegator.signUpReady(signUpRequest) .subscribeOn(Schedulers.io()) // 网络请求在IO线程执行 .observeOn(AndroidSchedulers.mainThread()) // 回调在主线程处理 .doOnNext { response -> // 每次拿到响应后,更新成功状态 isSignUpReady = response.isSuccessful // 这里可以添加你的响应处理逻辑,比如更新UI、保存数据等 if (isSignUpReady) { // 成功后的操作,比如提示用户、跳转页面 } } .repeatUntil { isSignUpReady } // 当状态为true时停止轮询 .subscribe( { /* 正常订阅的回调,这里可以留空或者复用doOnNext的逻辑 */ }, { error -> // 处理请求错误,比如网络异常等 error.printStackTrace() } )
关键逻辑说明
doOnNext的作用:在每次获取到signUpReady的响应后,先更新isSignUpReady的状态,这样repeatUntil就能根据这个状态判断是否停止轮询。repeatUntil的判断逻辑:每次上游Observable完成(不管成功还是失败),都会调用这个lambda。如果isSignUpReady为true,就停止重复订阅;否则会再次发起signUpReady请求,实现轮询效果。- 错误处理:别忘了在
subscribe中处理错误情况,避免网络异常导致轮询意外终止。
额外提示
如果你的轮询需要间隔时间(比如每隔3秒请求一次),可以在repeatUntil之前加上delay操作符:
.doOnNext { ... } .delay(3, TimeUnit.SECONDS) // 每次请求后等待3秒再判断是否重复 .repeatUntil { isSignUpReady }
内容的提问来源于stack exchange,提问作者Jono
相关产品推荐
相关产品推荐

