android - 为什么我无法从 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)
解决方案
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 对象,请使用我编辑的代码。应该不错。
推荐阅读
- r - 如何生成具有不同方差(异方差)的随机数据。在 R 中
- javascript - 使用 window.open() 函数打开已打开的选项卡而不重新加载已打开的选项卡
- javascript - 从 Devtools 处理组件删除
- javascript - 如何使用 Puppeteer 处理弹出窗口
- java - 在我的数组中找到中位数,同时将数字从小到大排序
- angularjs - 为什么 dateAdapter.setLocale 默认为某些语言?
- javascript - 如何使用 Javascript 将样式表应用于元素
- javascript - React-Bootstrap-TypeAhead 在尝试更改已选择的选项时给出错误
- javascript - 如何将包含数组的字符串转换为具有不同格式的数组
- elasticsearch - Elasticsearch - 获取所有文档的所有嵌套对象