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

使用Retrofit2的Android应用JSON查询异常,无法深度解析数据

Hey there! Let’s figure out why you’re hitting that onFailure when trying to pull the stormName field—Retrofit + GSON parsing issues usually boil down to mismatched entity classes or hidden JSON structure quirks. Let’s break this down step by step:

1. First: Fix the Entity Class <-> JSON Structure Mismatch

This is the #1 culprit for parsing failures. Let’s align your data classes with the actual JSON hierarchy:

  • From the JSON path you mentioned ($.currenthurricane.[stormInfo].stormName), double-check if stormInfo is a single object or an array in the raw JSON. If it’s a single object (not wrapped in []), defining stormInfo as a List<StormInfo> in your CurrentHurricane class will break parsing—GSON can’t convert an object to a list.
  • Also, ensure field names match exactly (or use @SerializedName if you’re using different variable names in Kotlin).

Here’s a corrected example based on typical hurricane API structures:

data class Cyclones(
    val currenthurricane: List<CurrentHurricane>
)

data class CurrentHurricane(
    @SerializedName("stormInfo") // Match JSON field name exactly
    val stormInfo: StormInfo // Use a single object, not List, if stormInfo isn't an array
)

data class StormInfo(
    @SerializedName("stormName")
    val stormName: String
)

2. Debug the Exact Failure Reason

Stop guessing—get the real error message from onFailure:

override fun onFailure(call: Call<Cyclones>, t: Throwable) {
    t.printStackTrace() // Check Logcat for details like "Expected BEGIN_OBJECT but was BEGIN_ARRAY"
}

This will tell you exactly where the parsing broke (e.g., array vs object mismatch, missing fields).

3. Test Parsing Step-by-Step

Don’t jump straight to stormName—validate each layer first:

override fun onResponse(call: Call<Cyclones>, response: Response<Cyclones>) {
    if (response.isSuccessful) {
        val cyclones = response.body()
        // First check if currenthurricane exists and has data
        cyclones?.currenthurricane?.let { hurricaneList ->
            if (hurricaneList.isNotEmpty()) {
                // Test the first hurricane entry first (avoid index out of bounds)
                val firstHurricane = hurricaneList[0]
                // Print the hurricane object to see if stormInfo is parsed correctly
                Log.d("ParsingTest", "First hurricane: $firstHurricane")
                // Now try to get stormName
                firstHurricane.stormInfo?.stormName?.let { name ->
                    Log.d("StormName", "Found: $name")
                } ?: Log.d("ParsingTest", "stormInfo or stormName is null")
            }
        }
    }
}

4. Double-Check Retrofit Setup

Make sure you’ve added the GSON converter factory to your Retrofit instance—without it, Retrofit can’t parse JSON into your data classes:

val retrofit = Retrofit.Builder()
    .baseUrl("https://api.myjson.com/")
    .addConverterFactory(GsonConverterFactory.create())
    .build()

5. Once Parsing Works: Connect to RecyclerView

Once you can reliably fetch stormName (or full hurricane objects), pass the list to your RecyclerView adapter:

// In your onResponse
cyclones?.currenthurricane?.let { hurricaneList ->
    val adapter = HurricaneAdapter(hurricaneList)
    recyclerView.adapter = adapter
}

Your adapter can then extract stormName from each CurrentHurricane item in onBindViewHolder.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:27:44