如何使用 Retrofit 解析对象内部的对象数组 json
How to parse json array of objects inside object using Retrofit
我正在尝试解析 JSON (https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json) 以在 RecyclerView 中显示数据,但出现错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 13534
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
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:919)
我看到问题是 JSON 只包含 1 个对象(口袋妖怪),并且在这个对象中有不同的口袋妖怪数组。我不知道如何解析 JSON 中上层对象中的数组。我应该改变什么才能让它发挥作用?
我想我应该保存这个 pokemon 对象然后解析它,但我不知道如何进入它。
谢谢。
API接口:
interface SimpleApi {
@GET("pokedex.json")
suspend fun getCustomPosts(): Response<List<Post>>
}
存储库:
class Repository {
suspend fun getCustomPosts(): Response<List<Post>>{
return RetrofitInstance.api.getCustomPosts()
}
}
视图模型:
class MainViewModel(val repository: Repository) : ViewModel() {
val myCustomPosts = MutableLiveData<Response<List<Post>>>()
fun getCustomPosts() {
viewModelScope.launch {
val response: Response<List<Post>> = repository.getCustomPosts()
myCustomPosts.value = response
}
}
}
主要活动:
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
private lateinit var binding: ActivityMainBinding
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
setRecyclerView()
val repository = Repository()
val viewModelFactory = MainViewModelFactory(repository)
viewModel = ViewModelProvider(this, viewModelFactory).get(MainViewModel::class.java)
viewModel.getCustomPosts()
viewModel.myCustomPosts.observe(this, Observer { response ->
if (response.isSuccessful) {
response.body()?.let { adapter.setData(it) }
} else {
Toast.makeText(this, response.code(), Toast.LENGTH_SHORT).show()
}
})
}
private fun setRecyclerView() {
adapter = MyAdapter()
recyclerView = binding.recyclerView
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
}
}
RecyclerView 适配器:
class MyAdapter() : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
private var postList = emptyList<Post>()
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val idView: TextView = view.findViewById(R.id.id_txt)
val nameView: TextView = view.findViewById(R.id.name_txt)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.row_layout, parent, false)
)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = postList[position]
holder.idView.text = currentItem.id.toString()
holder.nameView.text = currentItem.name
}
override fun getItemCount(): Int = postList.size
fun setData(newList: List<Post>){
postList = newList
notifyDataSetChanged()
}
}
Post:
data class Post(
@SerializedName("id")
val id: Int,
@SerializedName("name")
val name: String
)
尝试在响应对象中使用下一个 class:
data class PokedexResponse (
@SerializedName("pokemon")
val pokemons: List<Post>
)
interface SimpleApi {
@GET("pokedex.json")
suspend fun getCustomPosts(): Response<PokedexResponse>
}
我猜你错过了解析 pokemon
对象:
{
"pokemon": [{ ... }]
}
我正在尝试解析 JSON (https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json) 以在 RecyclerView 中显示数据,但出现错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 13534
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:80)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:243)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:153)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
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:919)
我看到问题是 JSON 只包含 1 个对象(口袋妖怪),并且在这个对象中有不同的口袋妖怪数组。我不知道如何解析 JSON 中上层对象中的数组。我应该改变什么才能让它发挥作用? 我想我应该保存这个 pokemon 对象然后解析它,但我不知道如何进入它。 谢谢。
API接口:
interface SimpleApi {
@GET("pokedex.json")
suspend fun getCustomPosts(): Response<List<Post>>
}
存储库:
class Repository {
suspend fun getCustomPosts(): Response<List<Post>>{
return RetrofitInstance.api.getCustomPosts()
}
}
视图模型:
class MainViewModel(val repository: Repository) : ViewModel() {
val myCustomPosts = MutableLiveData<Response<List<Post>>>()
fun getCustomPosts() {
viewModelScope.launch {
val response: Response<List<Post>> = repository.getCustomPosts()
myCustomPosts.value = response
}
}
}
主要活动:
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MainViewModel
private lateinit var binding: ActivityMainBinding
private lateinit var recyclerView: RecyclerView
private lateinit var adapter: MyAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
setRecyclerView()
val repository = Repository()
val viewModelFactory = MainViewModelFactory(repository)
viewModel = ViewModelProvider(this, viewModelFactory).get(MainViewModel::class.java)
viewModel.getCustomPosts()
viewModel.myCustomPosts.observe(this, Observer { response ->
if (response.isSuccessful) {
response.body()?.let { adapter.setData(it) }
} else {
Toast.makeText(this, response.code(), Toast.LENGTH_SHORT).show()
}
})
}
private fun setRecyclerView() {
adapter = MyAdapter()
recyclerView = binding.recyclerView
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
}
}
RecyclerView 适配器:
class MyAdapter() : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
private var postList = emptyList<Post>()
class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val idView: TextView = view.findViewById(R.id.id_txt)
val nameView: TextView = view.findViewById(R.id.name_txt)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.row_layout, parent, false)
)
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val currentItem = postList[position]
holder.idView.text = currentItem.id.toString()
holder.nameView.text = currentItem.name
}
override fun getItemCount(): Int = postList.size
fun setData(newList: List<Post>){
postList = newList
notifyDataSetChanged()
}
}
Post:
data class Post(
@SerializedName("id")
val id: Int,
@SerializedName("name")
val name: String
)
尝试在响应对象中使用下一个 class:
data class PokedexResponse (
@SerializedName("pokemon")
val pokemons: List<Post>
)
interface SimpleApi {
@GET("pokedex.json")
suspend fun getCustomPosts(): Response<PokedexResponse>
}
我猜你错过了解析 pokemon
对象:
{
"pokemon": [{ ... }]
}