【问题标题】:why I am not able to fetch data from Json Array为什么我无法从 Json Array 中获取数据
【发布时间】:2021-05-27 07:51:24
【问题描述】:

我无法从 https://api.coingecko.com/api/v3/exchanges.At 获取 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) 

【问题讨论】:

    标签: android android-studio kotlin parsing jsonparser


    【解决方案1】:
    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 对象,请使用我编辑的代码。应该不错。

    【讨论】:

    • 类型不匹配:推断类型是 CryptoList?但 List 是预期的 public fun MutableCollection.addAll(elements: Array): Boolean defined in kotlin.collections public fun MutableCollection.addAll(elements: Iterable): Boolean 定义在 kotlin.collections public fun MutableCollection.addAll(elements: Sequence) :在 kotlin.collections 中定义的布尔值未解析的参考:crypto1
    • 更改以覆盖 fun onResponse(call: Call, response: Response>) - 根据您的调用进行修改
    猜你喜欢
    • 2013-02-17
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多