如何正确地序列化/反序列化与Konlin中的复杂对象Gson?

时间:2018-05-15 21:14:05

标签: android json serialization kotlin gson

我有一个JSON字符串的以下字段:

action=surveyEventName
EventObject= serialized Event object (So in this field I want to serialize an object with Gson.

我遇到的问题是,当我尝试序列化Event对象时,我得到一个ANR。所以,我认为在设置Gson序列化方面我可能做错了。

事件类以这种方式定义:

class Event {

private var mActionName = ""
private var mId = ""
private lateinit var mConditions: MutableList<(Unit) -> Boolean>
private lateinit var mActions: MutableList<(Unit) -> Boolean>

fun getActionName(): String {
    return this.mActionName
}

fun setActionName(actionName: String) {
    this.mActionName = actionName
}

fun getId(): String {
    return this.mId
}

fun setId(id: String) {
    this.mId = id
}

fun addSingleCondition(condition: (Unit) -> Boolean) {
    if(::mConditions.isInitialized) {
        mConditions.add(condition)
    } else {
        mConditions = mutableListOf(condition)
    }
}

fun addSingleAction(action: (Unit) -> Boolean) {
    if(::mActions.isInitialized) {
        mActions.add(action)
    } else {
        mActions = mutableListOf(action)
    }
}

companion object {
    fun serializeEventList(event: List<Event>): String {
        return Gson().toJson(event) // ANR HERE!
    }

    fun deserializeEventList(jsonString: String): MutableList<Event> {
        return Gson().fromJson(jsonString,
                object : TypeToken<List<Event>>() {}.type)
    }
}
}

那么我想要我的最终JSON,如上所述,有一个动作标签和一个事件对象的序列化列表。我遇到的问题是,当我尝试序列化列表时,我得到一个ANR。

这是我的测试块:

//TESTBLOCK
fun testEvent() {
    //create test event
    val event = Event()
    event.setId("1")
    event.setActionName("testtag")
    event.addSingleCondition { testCondition1() }
    event.addSingleCondition { testCondition2() }
    event.addSingleAction { testAction1() }
    event.addSingleAction { testAction2() }
    val events = listOf(event)
    //create test JSON
    val jsonObject = JSONObject()
    jsonObject.put("tagfield", "testtag")
    val serializedObjectString = event.serializeEventList(events) 
    jsonObject.put("eventobjectfield", serializedObjectString)

}

之后我反序列化JSON eventobjectfield以再次使用Event对象,但是当我尝试序列化时,我得到了ANR。

我不确定Gson是否因为我添加到Event对象中的lambda而无法正常工作。我可能做错了什么?

1 个答案:

答案 0 :(得分:0)

我在一些实现上遇到了这个问题,直到我意识到如果您谨慎使用Gson,Gson会更好地工作。我发现在代码中无法正常工作的两件事是:

1)lateinit var:由于某些原因,使用这些变量解析类时Gson挂起。 2)具有覆盖值的成员变量或属性的继承:基本上,

如果我重写一个继承的值,Gson会抱怨我有两个使用以下相同名称示例定义的变量:

open class Person() {
    var id = 0
    var name = ""
    var age = 0
}

class AdultPerson() : Person() {
    override var age = 18
}

有Gson会抱怨该对象有2个具有相同名称age的变量。因此,要解决此问题,我必须在构造函数块或init块中更改age的默认值,以不覆盖该变量。

因此,照顾到这两件事,我设法使Gson将对象转换为字符串,即使它们具有复杂的继承,Collection或具有Collections变量的类。

我已经优化了我以前的Gson解析器,使其可以与其他类一起使用,到目前为止,它可以正常工作:

GsonParser.kt

object GsonParser {
    inline fun <reified T> toJson(src: T): String {
        return Gson().toJson(src)
    }

    inline fun <reified T> fromJson(src: String): T {
        val type = object : TypeToken<T>() {}.type
        return Gson().fromJson(src, type)
    }
}

希望有帮助!