Как создать новый необработанный тип для Parcelable - PullRequest
0 голосов
/ 12 июля 2019

У меня есть два класса.

Один - это класс Message, и он содержит Reaction Реакцию можно декодировать из одной строки.Я декодирую из объекта, который выглядит следующим образом:

{
[ ... message fields ... ],
"reaction" : "reactionCryingWithLaugh"

}

Код выглядит следующим образом:

@JsonClass(generateAdapter = true)
@Parcelize
data class Message(
    @get:Exclude override val id: String? = null,
    val creationDate: Timestamp? = null,
    val mime: String? = null,
    val senderId: String? = null,
    val text: String? = null,
    val emoji: Reaction? = null
) : Parcelable

data class Reaction(val name: String, val id: Int): Parcelable {
    override fun writeToParcel(dest: Parcel?, flags: Int) {
        dest?.writeString(name)
    }

    override fun describeContents (): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Reaction> {
        override fun createFromParcel(parcel: Parcel): Reaction {
            val name = parcel.readString()
            require(name != null)
            val reaction = reactionList.find { it.name == name }
            require(reaction != null)
            return reaction
        }

        override fun newArray(size: Int): Array<Reaction?> {
            return arrayOfNulls(size)
        }
    }
}

 val reactionList = arrayOf(
     Reaction("reactionCryingWithLaugh", R.drawable.ic_reaction_crying_with_laugh)
     [...]
     )

Когда я пытаюсь десериализовать, он терпит неудачу, даже не входя в createFromParcel

Как правильно это реализовать?

Я получаю ошибку: java.lang.RuntimeException: Не удалось десериализовать объект.Не удается преобразовать объект типа java.lang.String в тип net.sevendays.alpaca.ui.chat.Reaction (находится в поле 'lastMessage.emoji')

1 Ответ

0 голосов
/ 12 июля 2019

Когда я пытаюсь десериализовать, он не работает, даже не заходя в createFromParcel

Это потому, что вы десериализуете JSON, Parcelable используется только для чтения / записи Parcel s (двоичный формат для Android) .

Существует очень много библиотек Java для сериализации в JSON, но аннотация @JsonClass исходит от Moshi (скорее всего; возможно, это другая библиотека, которая использовала то же имя), поэтому вам нужно написать адаптер нестандартного типа для Reaction.Это должно быть так же просто, как

class ReactionAdapter {
  @ToJson 
  fun toJson(reaction: Reaction): String = reaction.name

  @FromJson 
  fun fromJson(text: String): Reaction {
    val reaction = reactionList.find { it.name == name }
    require(reaction != null)
    return reaction
  }
}

, а затем зарегистрировать его везде, где создается Moshi.Builder.

...