Kotlin中Retrofit+MVVM报Expected BEGIN_ARRAY错误该如何调整代码
报错根因
接口返回的JSON根节点是对象类型,但你的代码要求Retrofit直接将返回结果解析为List<Venue>数组类型,Gson解析时类型不匹配触发该错误。从你提供的JSON结构可以看出,场馆数组嵌套在response对象的venues字段内,需要新增外层包装类适配JSON结构。
代码修改步骤
1. 调整Model类结构
新增外层响应包装类,同时修正原有Venue类的id字段类型(你返回的id是字符串格式,不能用Int接收):
// 接口返回的最外层根对象 data class BaseResponse( val response: VenueResponse? = null ) // 对应JSON里的response字段对象 data class VenueResponse( val venues: List<Venue>? = null ) // 修正后的Venue类,id改为String类型 data class Venue( var id: String, var name: String )
2. 修改Endpoint接口返回类型
将原有的返回值从Call<List<Venue>>改为Call<BaseResponse>:
@GET("v2/venues/search") fun fetchAllVenues(): Call<BaseResponse>
3. 调整Repository的解析逻辑
修改Callback的泛型类型,从响应体中取出嵌套的venues数组:
class VenueRepository { private var apiInterface: VenuesEndpoint? = null init { apiInterface = ApiClient.getApiClient().create(VenuesEndpoint::class.java) } fun fetchAllVenues(): MutableLiveData<List<Venue>?> { val data = MutableLiveData<List<Venue>?>() apiInterface?.fetchAllVenues()?.enqueue(object : Callback<BaseResponse> { override fun onFailure(call: Call<BaseResponse>, t: Throwable) { data.value = null } override fun onResponse( call: Call<BaseResponse>, response: Response<BaseResponse> ) { val res = response.body() if (response.code() == 200 && res != null) { // 提取嵌套的场馆数组赋值给LiveData data.value = res.response?.venues } else { data.value = null } } }) return data } }
其他说明
ViewModel和上层调用逻辑不需要修改,Repository返回的LiveData类型仍然是List<Venue>,和原有逻辑完全兼容。如果后续接口新增外层状态字段,直接在BaseResponse中补充对应属性即可。
内容的提问来源于stack exchange,提问作者user3761485
相关产品推荐
相关产品推荐

