kotlin com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: ожидалось BEGIN_OBJECT, но было BEGIN_ARRAY в строке 1, путь 2 столбца $ - PullRequest
0 голосов
/ 30 сентября 2019

Я попытался проанализировать строку JSON с помощью OKHttp в Kotlin, но он выдал следующую ошибку, и приложение зависало:

2019-09-30 15: 27: 24.871 4808-4933 / com.kabelash.kotlinrepoE / AndroidRuntime: неустранимое исключение: процесс диспетчера OkHttp: com.kabelash.kotlinrepo, PID: 4808 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: ожидаемый BEGIN_OBJECT, но был BEGIN_ARRAY на пути строки 1, столбец 2, 2.gson.internal.bind.ReflectiveTypeAdapterFactory $ Adapter.read (ReflectiveTypeAdapterFactory.java:226)

My 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)

My 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 голосов
/ 30 сентября 2019

Ваша проблема с линией: val feed = gson.fromJson(body, Feed::class.java). Это берет JSON и пытается десериализовать в класс, который вы предоставили. Однако Feed - это объект, а ваш json находится в форме массива, поэтому при десериализации gson он ожидает { в начале. Вместо этого он видит [.

. Есть несколько вариантов, чтобы это исправить:

  • Если у вас есть доступ к источнику json, измените его так, чтобы он соответствовал Feed объект.
  • Изменить Feed на расширение List<T> или Array<T>.
  • Передать тип списка / массива в gson.
0 голосов
/ 30 сентября 2019

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) {
}
...