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

RxJava订阅返回空对象问题:接口数据与Model字段不匹配求助

问题排查与解决方案

1. JSON字段大小写不匹配(核心原因)

服务器返回的JSON中,数组字段是大写的Items:

{"Items": [ {"DistrictID": 1, "DistrictName": "sample string 2", ...}, ... ]}

但你的DistrictItems数据模型里定义的是小写的items:

data class DistrictItems(
    var items: List<TaxDistrictModel>?
)

Android常用的JSON序列化库(Gson、Moshi等)默认严格匹配字段名称大小写,所以无法把Items映射到items,直接导致it.items始终为null,日志自然输出null。

修复方法

有两种可选方案:

  • 直接把模型字段改成大写,和JSON字段完全一致:
    data class DistrictItems(
        var Items: List<TaxDistrictModel>?
    )
    
  • 保持模型字段的Kotlin小驼峰命名,用序列化注解指定对应JSON字段名(推荐):
    // Gson 注解写法
    data class DistrictItems(
        @SerializedName("Items")
        var items: List<TaxDistrictModel>?
    )
    
    // Moshi 注解写法
    data class DistrictItems(
        @Json(name = "Items")
        var items: List<TaxDistrictModel>?
    )
    

2. 异步操作的同步返回错误(潜在问题)

你的getRegions()函数试图同步返回districtModelTypeTitles,但RxJava的订阅是异步执行的:当return districtModelTypeTitles代码运行时,onNext回调还没触发,此时返回的是变量的初始值(大概率是null),会导致调用getRegions()的地方拿到错误结果。

修复方法

不要在异步场景下同步返回数据,改用回调、LiveData或Flow传递结果,以下是两种常用方案:

方案一:使用回调函数

fun getRegions(onResult: (DistrictItems?) -> Unit) {
    showLoading()
    api.getDistricts()
        .subscribeOn(Schedulers.io()) // 网络请求放在IO线程
        .observeOn(AndroidSchedulers.mainThread()) // UI操作回到主线程
        .subscribe(
            { result ->
                hideLoading()
                Log.d("qwerty", "$$$$$$$$ ${result.items?.size}")
                districtModelTypeTitles = result
                onResult(result) // 通过回调传递结果
            },
            { error ->
                hideLoading()
                showAlert(error)
                onResult(null)
            }
        )
        .disposedBy(compositeDisposable)
}

// 调用示例
getRegions { districtItems ->
    // 在这里处理返回的结果
}

方案二:使用LiveData(符合Android架构组件规范)

private val _districtItemsLiveData = MutableLiveData<DistrictItems?>()
val districtItemsLiveData: LiveData<DistrictItems?> = _districtItemsLiveData

fun getRegions() {
    showLoading()
    api.getDistricts()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
            { result ->
                hideLoading()
                Log.d("qwerty", "$$$$$$$$ ${result.items?.size}")
                districtModelTypeTitles = result
                _districtItemsLiveData.value = result // 发送结果到LiveData
            },
            { error ->
                hideLoading()
                showAlert(error)
                _districtItemsLiveData.value = null
            }
        )
        .disposedBy(compositeDisposable)
}

// 在Activity/Fragment中观察结果
viewModel.districtItemsLiveData.observe(this) { districtItems ->
    // 处理返回的数据
}

额外检查点

确认你的RxJava线程调度逻辑正确:网络请求必须在IO线程执行,UI更新操作要回到主线程。如果subscribeOnMain是自定义扩展函数,要确保内部已经正确设置subscribeOn(Schedulers.io())和observeOn(AndroidSchedulers.mainThread()),避免出现主线程阻塞或UI操作报错。


内容的提问来源于stack exchange,提问作者Akylbek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:03:28