Подтвердить что ты не робот

Использование Parceler с классом данных Kotlin с конструктором для сериализации

Есть ли способ использовать Parceler с классами данных и конструктором данных Kotlin для сериализации без использования аннотации @ParcelProperty для каждого поля?

Если я попытаюсь использовать библиотеку следующим образом:

@Parcel
data class Valve @ParcelConstructor constructor(val size: Int)

Я получаю Error:Parceler: No corresponding property found for constructor parameter arg0. Но если я добавлю @ParcelProperty("size"), то все будет отлично. Почему это?

Обновление:
Есть и другой способ использования этой библиотеки.
Я мог бы просто удалить аннотацию @ParcelConstructor, но тогда я получу ошибку
Error:Parceler: No @ParcelConstructor annotated constructor and no default empty bean constructor found.
Я думаю (не проверял его), я также мог бы сделать все параметры конструктора необязательными и добавить @JvmOverloads, но у меня есть побочный эффект, который я должен проверить на все свойства класса, если они являются нулевыми или нет.

Обновление 2:
Это то, что сработало для меня:

@Parcel
data class Valve(val size: Int? = null)

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

4b9b3361

Ответ 1

В соответствии с документами Parceler по умолчанию работает с общедоступными полями. Но обычный Kotlin data class (как в вашем примере) скорее является "традиционным getter/setter bean", так как каждое свойство Kotlin представлено частным полем и getter/[setter].

TL; ДР: Я думаю, что это сработает:

@Parcel(Serialization.BEAN)
data class Valve(val size: Int = 10)

Обратите внимание на значение по умолчанию, оно позволяет Kotlin автоматически генерировать дополнительный пустой конструктор, который требуется спецификацией Java Been.

Другим способом было бы отметить конструктор, который у нас уже есть:

@Parcel(Serialization.BEAN)
data class Driver @ParcelConstructor constructor(val name: String)

Конкретный документ: https://github.com/johncarl81/parceler#gettersetter-serialization

Ответ 2

Я знаю, что на этот вопрос уже есть ответ, но для будущих зрителей, которые также пытаются заставить Parceler работать с объектами данных kotlin, я написал новый процессор аннотаций, чтобы сгенерировать шаблон Parcelable для классов данных Kotlin. Он предназначен для значительного сокращения стандартного кода при создании классов данных Parcelable:

https://github.com/grandstaish/paperparcel

Использование:

Аннотируйте свой класс данных с помощью @PaperParcel, реализуйте PaperParcelable и добавьте статический экземпляр JVM сгенерированного CREATOR например:

@PaperParcel
data class Example(
  val test: Int,
  ...
) : PaperParcelable {
  companion object {
    @JvmField val CREATOR = PaperParcelExample.CREATOR
  }
}

Теперь ваш класс данных Parcelable и может быть передан непосредственно в Bundle или Intent

Изменить: обновить с последним API

Ответ 3

Просто добавьте конструктор по умолчанию:

@Parcel
data class Valve(val size: Int) {
    constructor() : this(0)
}

Ответ 4

если вы используете kotlin 1.1.4 или выше, очень просто использовать аннотацию @Parcelize

Для этого сначала добавьте это в build.gradle

android {
    //other codes

    //for using latest experimental build of Android Extensions
    androidExtensions {
        experimental = true
    }
}

Тогда ваш класс должен понравиться

@Parcelize
data class Valve(val size: Int? = null) : Parcelable