Android中RxJava/RxAndroid循环调用API重复传参问题求解
问题根源
你当前代码的问题在于:调用userRepository.saveUser(users[index])时,index初始值为0,此时已经创建了一个固定指向第一个用户的Single实例。后续的repeat操作只是重复订阅这个预先创建好的Single,并不会重新计算index来获取新用户,所以所有API请求都会发送同一个用户。
正确实现方案
要逐个按顺序保存用户,更合理的做法是用Observable.fromIterable遍历用户列表,再通过concatMap(保证顺序执行,前一个请求完成后再发起下一个)来逐个触发API调用。这种方式不需要手动维护index,逻辑更清晰且不易出错。
修改后的完整代码
data class User(val name: String, val age: Int) class ResultResponse( val ResultCode: Int = -1 ) fun saveUsers(users: List<User>) { // 遍历用户列表,逐个发起保存请求 Observable.fromIterable(users) .concatMap { user -> // 每个用户对应一个saveUser请求,切换到IO线程执行 userRepository.saveUser(user) .subscribeOn(Schedulers.io()) .doOnSubscribe { // 单个请求开始前的操作,比如显示加载状态 } .doFinally { // 单个请求完成后的操作,比如隐藏加载状态 } // 可选:如果需要在请求之间加延迟,在这里添加 .delay(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread()) .toObservable() // 把Single转成Observable,配合concatMap } .observeOn(AndroidSchedulers.mainThread()) .subscribe( { result -> // 单个用户保存成功的回调,可根据ResultCode处理 if (result.ResultCode == 0) { // 保存成功逻辑 } else { // 保存失败逻辑(非异常情况) } }, { error -> // 请求抛出异常的处理,比如网络错误 error.printStackTrace() }, { // 所有用户都保存完成的回调 // do something } ) .also { compositeDisposable.add(it) } }
代码说明
Observable.fromIterable(users):将用户列表转换为Observable,逐个发射每个用户对象。concatMap:按顺序处理每个用户对应的API请求,只有前一个请求完成后才会触发下一个,确保用户保存的顺序性。subscribeOn(Schedulers.io()):将API请求切换到IO线程执行,避免阻塞主线程。observeOn(AndroidSchedulers.mainThread()):将回调切换回主线程,方便更新UI。delay:如果需要在两次请求之间添加间隔,可保留这个操作;不需要的话可以删除。- 最终的
onComplete回调会在所有用户都保存完成后触发,适合做收尾操作。
可选优化(错误处理)
如果希望某个用户保存失败时,继续保存后续用户,可以在concatMap里添加错误处理:
.concatMap { user -> userRepository.saveUser(user) .subscribeOn(Schedulers.io()) .doOnSubscribe { /* ... */ } .doFinally { /* ... */ } .onErrorReturn { // 捕获异常,返回一个标识失败的ResultResponse ResultResponse(-2) } .toObservable() }
这样即使某个请求抛出异常,流也不会终止,会继续处理下一个用户,你可以在onNext回调里根据ResultCode == -2来判断该用户保存失败。
内容的提问来源于stack exchange,提问作者AndroidDev
相关产品推荐
相关产品推荐

