json 应为开始_ARRAY,但在第1行第2列路径$处为BEGIN_OBJECT,Retrofit 2 Android [重复]

mepcadol  于 2023-10-21  发布在  Android
关注(0)|答案(1)|浏览(114)

此问题已在此处有答案

Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2(2个答案)
6天前关闭
你能帮我看看代码吗?我不知道还需要做什么。我什么都试过了,现在我不知道还能做什么。
我需要得到'entries'数组来检索数据。下面是正在解析的JSON的链接:https://launchercontent.mojang.com/news.json

package com.mcbedrock.app.data

data class NewsEntry(

    val version: Int,

    val entries: List<Entry>

)

data class Entry(

    val cardBorder: Boolean,

    val category: String,

    val date: String,

    val id: String,

    val newsPageImage: NewsPageImage,

    val newsType: List<String>,

    val playPageImage: PlayPageImage,

    val readMoreLink: String,

    val tag: String,

    val text: String,

    val title: String

)

data class NewsPageImage(

    val dimensions: Dimensions,

    val title: String,

    val url: String

)

data class PlayPageImage(

    val title: String,

    val url: String

)

data class Dimensions(

    val height: Int,

    val width: Int

)


My adapter:

package com.mcbedrock.app.adapter

import android.content.Context

import android.view.LayoutInflater

import android.view.View

import android.view.ViewGroup

import android.widget.ImageView

import androidx.recyclerview.widget.RecyclerView

import com.bumptech.glide.Glide

import com.google.android.material.button.MaterialButton

import com.google.android.material.textview.MaterialTextView

import com.mcbedrock.app.R

import com.mcbedrock.app.data.NewsEntry

class NewsAdapter(var context: Context, var newsEntryList: MutableList<NewsEntry>):

    RecyclerView.Adapter<NewsAdapter.MyViewHolder>() {

    inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        var titleView: MaterialTextView

        var textView: MaterialTextView

        var imageView: ImageView

        var readMoreBtn: MaterialButton

        init {

            titleView = itemView.findViewById(R.id.TitleView)

            textView = itemView.findViewById(R.id.TextView)

            imageView = itemView.findViewById(R.id.ImageView)

            readMoreBtn = itemView.findViewById(R.id.ActionButton)

        }

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): NewsAdapter.MyViewHolder {

        return MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item_news_card, parent, false))

    }

    override fun onBindViewHolder(holder: NewsAdapter.MyViewHolder, position: Int) {

        val entry = newsEntryList[position].entries[position]

        holder.titleView.text = entry.title

        holder.textView.text = entry.text

        Glide.with(context)

            .load("https://launchercontent.mojang.com/" + entry.newsPageImage.url)

            .into(holder.imageView)

    }

    override fun getItemCount(): Int {

        return newsEntryList.size

    }

}

My fragment:

package com.mcbedrock.app.ui.fragment

import android.os.Bundle

import android.util.Log

import androidx.fragment.app.Fragment

import android.view.LayoutInflater

import android.view.View

import android.view.ViewGroup

import androidx.lifecycle.ViewModelProvider

import androidx.navigation.fragment.findNavController

import androidx.recyclerview.widget.LinearLayoutManager

import androidx.recyclerview.widget.RecyclerView

import androidx.recyclerview.widget.RecyclerView.LayoutManager

import com.mcbedrock.app.R

import com.mcbedrock.app.adapter.NewsAdapter

import com.mcbedrock.app.databinding.FragmentFirstBinding

import com.mcbedrock.app.viewmodel.NewsViewModel

class FirstFragment : Fragment() {

    var viewModel: NewsViewModel? = null

    var recyclerView: RecyclerView? = null

    var adapter: NewsAdapter? = null

    var layoutManager: LayoutManager? = null

    private var _binding: FragmentFirstBinding? = null

    private val binding get() = _binding!!

    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

    }

    override fun onCreateView(

        inflater: LayoutInflater, container: ViewGroup?,

        savedInstanceState: Bundle?): View? {

        _binding = FragmentFirstBinding.inflate(inflater, container, false)

        return binding.root

    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)

        recyclerView = _binding?.recyclerview

        layoutManager = LinearLayoutManager(requireActivity())

        recyclerView!!.layoutManager = layoutManager

        viewModel = ViewModelProvider(this)[NewsViewModel::class.java]

        viewModel!!.getNewsList.observe(viewLifecycleOwner) { newsEntry ->

            if (newsEntry != null) {

                Log.e("NewsFragment", "NewsList: " + newsEntry.get(0).entries.get(0).title)

                if (newsEntry != null) {

                    adapter = NewsAdapter(requireActivity(), newsEntry)

                    adapter!!.notifyDataSetChanged()

                    recyclerView!!. adapter = adapter

                }

            }

        }

        binding.buttonFirst.setOnClickListener {

            findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)

        }

    }

    override fun onDestroyView() {

        super.onDestroyView()

        _binding = null

    }

}

我尝试修改数据类并在适配器中合并数据检索。

lmyy7pcs

lmyy7pcs1#

看起来你已经指定了List<NewsEntry>作为请求的返回类型,所以序列化库试图将其解析为JsonArray,但由于响应是JsonObject,因此它失败了。
1.要使其工作,您可以尝试将List<NewsEntry>替换为NewsEntry,并进行所有其他相关更改。
1.或者,您可以考虑使用类型适配器删除NewsEntry模型,以便返回类型为List<Entry>。如果你正在使用Gson,它可能看起来像这样:

class EntriesTypeAdapterFactory : TypeAdapterFactory {

    private val typeToken: TypeToken<List<Entry>> = object : TypeToken<List<Entry>>() {}

    override fun <R : Any?> create(gson: Gson, type: TypeToken<R>): TypeAdapter<R>? {
        if (!typeToken.isAssignableFrom(type.type)) {
            return null
        }
        val delegateAdapter = gson.getDelegateAdapter(this, typeToken)
        val elementAdapter = gson.getAdapter(JsonElement::class.java)
        val result = object : TypeAdapter<List<Entry>>() {
            override fun write(out: JsonWriter, value: List<Entry>) {
                //we don't serialize it so no logic specified
            }

            override fun read(`in`: JsonReader): List<Entry>? {
                val jsonElement = elementAdapter.read(`in`)
                return delegateAdapter.fromJsonTree(
                    (jsonElement as JsonObject).getAsJsonArray("entries")
                )
            }
        }.nullSafe()

        return result as TypeAdapter<R>
    }
}

然后,将其添加到Gson中,如下所示:

.registerTypeAdapterFactory(EntriesTypeAdapterFactory())

相关问题