无法使用 Kotlin 中的序列化从 json 字符串解码对象的数组列表



所以,我有ActorModel类,其中包括MovieModel的arraylist。我试图对其进行编码并将其捆绑发送到下一个活动。但是,它是在说:

kotlinx.serialization.json.internal.JsonDecodingException: Expected start of the object '{', but had 'EOF' instead at path: $
JSON input: kotlinx.serialization

这是我的演员模型类:

package com.sanjarbek.flixster2
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.Serializable

@Serializable
data class ActorModel(
val name: String,
val popularity: String,
val profile_path: String, ) {
var movieModelArrayList: ArrayList<MovieModel> = ArrayList<MovieModel>()
set(value) {field = value}
get() = field
fun mainMovie(): String {
val json = Json.encodeToString<ArrayList<MovieModel>>(movieModelArrayList)
return json
}
fun main(): String {
val json = Json.encodeToString(ActorModel(name, popularity, profile_path))
return json
}
}

其次是电影模型类:

package com.sanjarbek.flixster2
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.Serializable
@Serializable
data class MovieModel (
private val original_title: String="",
private val poster_path: String="",
private val overview: String=""
) {
fun get_title(): String{
return original_title
}
fun get_image(): String{
return poster_path
}
fun get_description(): String{
return overview
}
}

这是我尝试将其与捆绑包一起发送的代码:

holder.image.setOnClickListener {
val intent = Intent(context, ActorInfoActivity::class.java)
intent.putExtra("image", image_url)
intent.putExtra("name", model.name)
intent.putExtra("model", model.main())
context.startActivity(intent)
}

以及我接收和解码它的地方:

val actor = Json.decodeFromString<ActorModel>("kotlinx.serialization")
val movies = Json.decodeFromString<ArrayList<MovieModel>>("kotlinx.serialization")
Log.d("TAG", "onCreate: $actor"
Log.d("TAG", "onCreate: $movies")

如果您的问题是如何将上述对象传递给另一个活动,那么这不需要 JSON 对象。Android 为我们提供了开箱即用的工具。我重写了你的课程:

演员模型

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
data class ActorModel (
val name: String,
val popularity: String,
val profilePath: String,
var movieModelArrayList: MutableList<MovieModel> = mutableListOf()): Parcelable {
override fun toString(): String {
return "ActorModel(name=$name, popularity=$popularity, profilePath=$profilePath)n" +
"movieModelArrayList=$movieModelArrayList"
}
}

电影模型

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
@Parcelize
data class MovieModel (
val original_title: String = "TestTitle",
val poster_path: String = "./Test",
val overview: String = "Test"
): Parcelable

我提请您注意@Parcelize注释和接口Parcelable- 这是对代码最重要的更改。Parcelable过程比Serializable快得多。其中一个原因是我们对序列化过程是明确的,而不是使用反射来推断它。实际上,我们必须手动实现Parcelable接口的方法。但是 Kotlin 的创建者照顾了我们并添加了@Parcelize注释,这为我们完成了所有肮脏的工作。默认情况下,它不可用,如何启用它在答案中有详细说明。

发送数据

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
class TestActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val actor = ActorModel("Alex", "10", "./profiles")
actor.movieModelArrayList.add(MovieModel())
val intent = Intent(this, MainActivity::class.java)
val bundle = Bundle()
bundle.putParcelable("actor", actor)
intent.putExtras(bundle)
startActivity(intent)
}
}

获取数据

class MainActivity: AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val actor = intent.extras?.get("actor") as ActorModel
Log.i("Test", actor)
}
}

一个小题外话

MovieModel类中,您不需要 getter,因为您已经将字段声明为 val - 它们不再是可变和只读的。因此,私有修饰符也没有意义。它不再是 Java,放松并享受 Kotlin :)

最新更新