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

Android Kotlin中Volley JsonObjectRequest始终触发VolleyError问题

问题根源

报错来自两个核心逻辑错误:

  1. Volley请求类型不匹配:从你贴的异常信息Value [{"dbn":"02M260"...}]可以明确看到,接口返回的是JSON数组结构(内容以[开头),但你使用了JsonObjectRequest发起请求——这个请求类默认会把响应解析为单个JSON对象(以{开头的结构),Volley在内部预解析阶段就会抛出JSONException,直接进入错误回调,你写在成功回调里的Gson解析逻辑根本不会执行。
  2. Gson解析与LiveData使用错误:即使请求成功,你写的解析逻辑也无法正常触发UI更新:一是错误尝试把JSON直接反序列化为MutableLiveData类型,LiveData是数据容器不是业务数据模型;二是直接把ViewModel中提前初始化的schoolsData变量替换成了Gson生成的新对象,View层注册的观察者是绑定在旧实例上的,永远收不到数据更新。
修复方案
  • 将Volley的请求类从JsonObjectRequest替换为JsonArrayRequest,匹配接口返回的数组结构。
  • 修正Gson解析逻辑:通过TypeToken指定解析类型为List<SchoolsData>,解析完成后调用postValue方法把数据设置到你提前定义好的schoolsData LiveData实例上,禁止重新给schoolsData变量赋值。
  • 额外注意:如果后续遇到数值类型解析错误,可先将SchoolsData中的total_students、graduation_rate字段类型改为String接收,拿到值后再手动转换为对应数值类型,避免接口返回值类型和本地定义不匹配导致解析失败。
修正后的ViewModel核心代码
class SchoolViewModel: ViewModel() {

    private val schoolsData = MutableLiveData<List<SchoolsData>>()
    val _schoolsData: LiveData<List<SchoolsData>> = schoolsData

    private var satData = MutableLiveData<SATData>()
    val _satData: LiveData<SATData> = satData

    private val API_Schools: String = "https://data.cityofnewyork.us/resource/s3k6-pzi2.json"
    private val API_SAT: String = "https://data.cityofnewyork.us/resource/f9bf-2cp4.json"

    fun getData(context: Context) {
        val requestQueue: RequestQueue = Volley.newRequestQueue(context.applicationContext)
        // 替换为数组请求
        val jsonArrayRequest = JsonArrayRequest(Request.Method.GET, API_Schools, null,
            { response ->
                try {
                    val gson = Gson()
                    // 处理泛型擦除问题,正确解析为学校列表
                    val listType = object : TypeToken<List<SchoolsData>>() {}.type
                    val schoolList: List<SchoolsData> = gson.fromJson(response.toString(), listType)
                    // 给原有LiveData实例设置数据,不要重新赋值变量
                    schoolsData.postValue(schoolList)
                }catch (e: Exception){
                    Log.e("PARSE_ERROR", e.stackTraceToString())
                }
            }, { error ->
                Log.e("REQUEST_ERROR", error.stackTraceToString())
            })
        requestQueue.add(jsonArrayRequest)
    }
}

替换后重新运行即可正常拿到数据,RecyclerView会自动触发更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 06:03:19