You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:35:30