Android Kotlin MVVM架构中JSON解析异常:nestedData为null
问题解决:API响应字段映射失败导致nestedData为null
核心原因
API返回的JSON外层数组字段是"data",但你定义的CompletedTaskSummaryResponse数据类中对应的字段是nestedData,序列化框架(如Gson/Moshi)无法自动匹配字段名,导致nestedData始终为null。
解决方案
1. 修正数据类字段映射
有两种可行方式:
方式一:直接修改字段名匹配API
data class CompletedTaskSummaryResponse<T>( val rId: Int, // 将nestedData改为data,与API返回的字段名完全一致 val data: List<NestedData<T>>?, val eId: Int?, val eDesc: String? ) data class NestedData<T>( val data: List<T>? )
方式二:用@SerializedName注解映射(保留原有字段名)
如果不想修改字段名,给nestedData添加注解指定对应JSON字段:
import com.google.gson.annotations.SerializedName data class CompletedTaskSummaryResponse<T>( val rId: Int, @SerializedName("data") // 明确指定对应JSON中的"data"字段 val nestedData: List<NestedData<T>>?, val eId: Int?, val eDesc: String? ) data class NestedData<T>( val data: List<T>? )
2. 调整ViewModel中的解析逻辑
如果采用方式一修改了字段名,ViewModel里的解析代码需要对应调整:
authResponse.data?.let { responseObject -> val nestedList = responseObject.firstOrNull()?.data.orEmpty() if (nestedList.isNotEmpty()) { _completedTaskSummaryList.value = nestedList repository.saveCompletedTaskSummaryList(nestedList) completedTaskListener?.onSuccess(nestedList) } return@main }
3. 简化DAO中的suspend函数(可选优化)
Room原生支持suspend函数,无需手动用suspendCoroutine包裹,直接定义suspend版本的批量插入即可:
@Dao interface CompletedTaskSummaryReportDao { // Room自动处理后台线程,无需额外包装 @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun upsert(completedTaskList: List<CompletedTaskSummaryReport>) @Query("Select * from completedtasksummary") fun getCompletedTaskSummaryReport(): LiveData<List<CompletedTaskSummaryReport>> }
此修改可移除冗余的upsertNonSuspending函数,让代码更简洁。
验证修改
重新调试后,response.body()中的对应字段(data或nestedData)会正确映射API返回的数组,后续的数据解析、存储流程即可正常执行。
内容的提问来源于stack exchange,提问作者Moin Khan
相关产品推荐
相关产品推荐

