Класс данных Kotlin |добавить мои собственные переменные, кроме ключей JSON - PullRequest
0 голосов
/ 25 мая 2018

Я использую модификацию и kotlin для моего приложения andorid.

Для одного из моих API у меня есть следующие классы данных

class Set(val set_id: Long, val tickets: List<Ticket>, val timer: Int) {}
class Ticket(val ticket_id: Long, val rows: List<Row>) {}
class Row(val row_id: Long, val row_numbers: List<Int>) {}

Пример JSON DATA

{
  "set_id": 60942,
  "tickets": [
    {
      "ticket_id": 304706,
      "rows": [
        {
          "row_id": 914116,
          "row_numbers": [
            0,
            11,
            21,
            0,
            42,
            52,
            0,
            76,
            85
          ]
        }
      ]
    }
  ],
  "timer": 12
}

Set класс содержит список Ticketи каждый тикет имеет список Row

Мой объект JSON содержит только эти значения, и до сих пор он работал нормально.Также работает преобразование.

Проблема: Я хочу добавить свое собственное логическое поле / переменную isPlaying для класса Ticket, которое будет обновлено в приложении позже.Но это поле должно быть установлено в true по умолчанию.

Итак, я пробовал это

class Ticket(val ticket_id: Long, val rows: List<Row>, var isPlaying: Boolean = true) {}

и это

class Ticket(val ticket_id: Long, val rows: List<Row>) {
    var isPlaying: Boolean = true
}

ПРИМЕЧАНИЕ: JSON неесть ключ isPlaying, я хочу его только для логики приложения.

Оба не работали, isPlaying всегда показывает false.Я хочу, чтобы оно было true по умолчанию.

Пожалуйста, помогите мне.Спасибо!

Ответы [ 3 ]

0 голосов
/ 25 мая 2018

Аргументы по умолчанию не будут работать в классе данных в случае, когда объекты создаются с модификацией из-за используемой ниже библиотеки синтаксического анализа, которая, вероятно, создает объекты без вызова конструктора.Например, Gson использует sun.misc.Unsafe для создания объектов.

Что вы можете сделать - это добавить свойство поддержки для полей со значениями по умолчанию:

class Ticket(
    val ticket_id: Long, 
    val rows: List<Row>, 
    private var _isPlaying: Boolean? = true
) {
    var isPlaying
        get() = _isPlaying ?: true
        set(value) {
            _isPlaying = value
        }
}
0 голосов
/ 25 мая 2018

Корень проблемы заключается в том, что GSON создает объект не через вызов конструктора, а через небезопасный персонал.Таким образом, это приводит к таким ошибкам, как нулевая безопасность или инициализация свойств.

Единственный способ, которым я знаю, как обойти ваше дело, выглядит так:

class Ticket(val ticket_id: Long, val rows: List<Row>) {
    private var _isPlaying: Boolean? = null
    var isPlaying: Boolean
        get() = _isPlaying ?: true // <-- default value
        set(value) {
            _isPlaying = value
        }
}

Здесь мы создаем одно свойство поддержки _isPlaying, который будет инициализирован нулем GSON.Затем мы добавляем пользовательский метод get и set для открытого свойства, которое проверяет каждое его вызванное значение, если _isPlaying равно нулю.И если это так, он возвращает ваше значение по умолчанию.В противном случае он возвращает значение, хранящееся в _isPlaying

Да, это выглядит некрасиво.В противном случае вам следует рассмотреть возможность использования другой библиотеки json, например, Джексона, которая, как я знаю, хорошо поддерживает Kotlin.

0 голосов
/ 25 мая 2018

С использованием GsonBuilder setFeildNamePolicy

 val gson = GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .create()


        val info = gson.fromJson(json, Account::class.java)


data class Account(
        @SerializedName("user_name") var userName: String = "",
        @SerializedName("ticket_id")  var ticketId: String = "",
        @SerializedName("row_id")  var rowId: String = "")

}
...