首页 > 解决方案 > 为什么我无法从 Json Array 中获取数据

问题描述

我无法从https://api.coingecko.com/api/v3/exchanges获取 Json 数据。最后我粘贴了 LogCat 的日志。

有人请帮助我吗?不要被我冗长的代码冒犯!!!

-------------------------这是我的(MainActivity.kt)-- ----------------

package com.example.cryptotracker

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MainActivity : AppCompatActivity() {
    private lateinit var mAdapter :CryptoAdapter
    private var crypto1 = mutableListOf<Crypto>()

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mAdapter = CryptoAdapter(this,crypto1)
        recyclerView.adapter = mAdapter
        recyclerView.layoutManager = LinearLayoutManager(this)



        getCrypto()


    }

    private fun getCrypto() {
        val crypto:Call<CryptoList> = CryptoService.cryptoInstance.getExchanges()
        crypto.enqueue(object : Callback<CryptoList> {
            override fun onResponse(call: Call<CryptoList>, response: Response<CryptoList>) {
                val crypto:CryptoList? = response.body()
                if(crypto!=null)
                {
                    Log.d("THISSSSS",crypto.toString())
                    crypto1.addAll(crypto.crypto1)
                    mAdapter.notifyDataSetChanged()

                }
            }

            override fun onFailure(call: Call<CryptoList>, t: Throwable) {
                Log.d("ERRRRRROR","ERROR IN FETCHING",t)
            }
        } )
    }
}

---------CryptoAdapter(适配器和 ViewHolder)------------

package com.example.cryptotracker

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide

class CryptoAdapter(val context:Context, val crypto1:List<Crypto> ):RecyclerView.Adapter<CryptoViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CryptoViewHolder {
        val view:View = LayoutInflater.from(context).inflate(R.layout.item_crypto,parent,false)
        return CryptoViewHolder(view)
    }

    override fun onBindViewHolder(holder: CryptoViewHolder, position: Int) {
        val current_item:Crypto = crypto1[position]

        holder.cryptoName.text = current_item.name
        holder.cryptoCountry.text = current_item.country
        holder.cryptoUrl.text = current_item.url
        holder.cryptoVolume.text = current_item.trade_volume_24h_btc
        Glide.with(context).load(current_item.image).into(holder.cryptoImage)
    }

    override fun getItemCount(): Int {
      return  crypto1.size
    }

}


class CryptoViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    var cryptoName = itemView.findViewById<TextView>(R.id.cryptoName)
    var cryptoImage = itemView.findViewById<ImageView>(R.id.cryptoImage)
    var cryptoCountry = itemView.findViewById<TextView>(R.id.cryptoCountry)
    var cryptoUrl = itemView.findViewById<TextView>(R.id.cryptoUrl)
    var cryptoVolume = itemView.findViewById<TextView>(R.id.cryptoVolume)



}

------------------------CryptoTracker.kt------------ --------

package com.example.cryptotracker

import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.http.GET
import retrofit2.create
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.Query

const val BASE_URL = "https://api.coingecko.com/"


interface CryptoInteface {
    @GET("api/v3/exchanges")
    fun getExchanges(): Call<CryptoList>
}

object CryptoService {
    val cryptoInstance: CryptoInteface

    init {
        val retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create())
            .build()

        cryptoInstance = retrofit.create(CryptoInteface::class.java)


    }
}

--------------------------这些是我的数据类------------

package com.example.cryptotracker

data class CryptoList (
    val crypto1:List<Crypto>
    )
package com.example.cryptotracker

data class Crypto (
    val name:String,
    val country:String,
    val url:String,
    val image:String,
    val trade_volume_24h_btc:String,
    val trade_volume_24h_btc_normalized:String

    )

======================LogCat ======================

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
        at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)
     Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
        at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:386)
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:215)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:40) 
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27) 
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243) 
        at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:153) 
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:174) 
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32) 
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) 
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) 
        at java.lang.Thread.run(Thread.java:764) 

标签: androidandroid-studiokotlinparsingjsonparser

解决方案


private fun getCrypto() {
        val crypto:Call<CryptoList> = CryptoService.cryptoInstance.getExchanges()
        crypto.enqueue(object : Callback<CryptoList> {
            override fun onResponse(call: Call<List<CryptoList>>, response: Response<List<CryptoList>>) {
                val crypto1:List<CryptoList> = response.body()
                if(crypto!=null)
                {
                    Log.d("THISSSSS",crypto.toString())
                    crypto1.addAll(crypto.crypto1)
                    mAdapter.notifyDataSetChanged()

                }
            }

            override fun onFailure(call: Call<CryptoList>, t: Throwable) {
                Log.d("ERRRRRROR","ERROR IN FETCHING",t)
            }
        } )
    }
}

您正在获取 JSON 对象数组,但您正试图解析为单个 JSON 对象,请使用我编辑的代码。应该不错。


推荐阅读