kotlin com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_OBJECT,但在第1行第2列路径处为BEGIN_ARRAY

时间:2019-09-30 15:15:13

标签: java android json kotlin okhttp

我试图在Kotlin中使用OKHttp解析JSON字符串,但它给了我以下错误,并且应用程序崩溃了:

2019-09-30 15:27:24.871 4808-4933 / com.kabelash.kotlinrepo E / AndroidRuntime:致命例外:OkHttp Dispatcher         流程:com.kabelash.kotlinrepo,PID:4808         com.google.gson.JsonSyntaxException:java.lang.IllegalStateException:预期为BEGIN_OBJECT,但在第1行第2列路径处为BEGIN_ARRAY             在com.google.gson.internal.bind.ReflectiveTypeAdapterFactory $ Adapter.read(ReflectiveTypeAdapterFactory.java:226)

我的MainActivity.kt

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        recyclerView_main.layoutManager = LinearLayoutManager(this);

        fetchJson()

    }

    fun fetchJson() {
        val url = "https://api.myurl.com/"

        val request = Request.Builder().url(url).build()
        val client = OkHttpClient()
        client.newCall(request).enqueue(object: Callback{
            override fun onResponse(call: Call, response: Response) {
                val body = response.body?.string()
                println(body)

                val gson = GsonBuilder().create()

                val feed = gson.fromJson(body, Feed::class.java)

                runOnUiThread {
                    recyclerView_main.adapter = MainAdapter(feed)
                }
            }

            override fun onFailure(call: Call, e: IOException) {
                println("Request Failed")
            }
        })
    }
}

class Feed (val name: String, val created_at: String, val owner: Owner)

class Owner (val login: String, val avatar_url: String)

我的MainAdapter.kt

class MainAdapter(val feed: Feed): RecyclerView.Adapter<CustomViewHolder>(){

    override fun getItemCount(): Int {
        return feed.name.count()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val rowCell = layoutInflater.inflate(R.layout.repo_row, parent, false)
        return CustomViewHolder(rowCell)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        val fd = feed.name.get(position)
        holder.view.titleText.text = fd.toString()
    }

}

class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
}

我在其中花费了很多时间,但仍然无法弄清楚。我该如何解决?有什么建议吗?

2 个答案:

答案 0 :(得分:0)

API返回一个Json对象数组。因此,您需要将其解析为数组。

您应该放val feed = gson.fromJson(body, Feed::class.java)而不是val feed = gson.fromJson(body, Array<Feed>::class.java)

MainAdaptor

class MainAdapter(val feed: Array<Feed>): RecyclerView.Adapter<CustomViewHolder>(){

    override fun getItemCount(): Int {
        return feed.count()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        val rowCell = layoutInflater.inflate(R.layout.repo_row, parent, false)
        return CustomViewHolder(rowCell)
    }

    override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
        val fd = feed.get(position)
        holder.view.titleText.text = fd.name.toString()
    }

}

class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
}

答案 1 :(得分:0)

您的问题所在的行是val feed = gson.fromJson(body, Feed::class.java)。这将使用json并尝试反序列化到您提供的类中。但是,Feed是一个对象,而您的json是数组形式的,因此当gson反序列化时,它期望在开始时使用{。相反,它看到的是[

有两个选项可以解决此问题:

  • 如果您有权访问json的源,请进行修改以适合Feed对象。
  • 更改Feed以扩展List<T>Array<T>
  • 将列表/数组类型传递给gson。