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
相关产品推荐
相关产品推荐

