Existe-t-il un moyen d'utiliser Parceler avec les classes de données Kotlin et le constructeur pour la sérialisation sans utiliser d'annotation @ParcelProperty
pour chaque champ?
Si j'essaie d'utiliser une bibliothèque comme celle-ci:
@Parcel
data class Valve @ParcelConstructor constructor(val size: Int)
Je reçois Error:Parceler: No corresponding property found for constructor parameter arg0
. Mais si j'ajoute @ParcelProperty("size")
cela fonctionne très bien.
Pourquoi donc?
Mise à jour :
Il existe une autre façon d'utiliser cette bibliothèque.
Je pourrais simplement supprimer l'annotation @ParcelConstructor
, mais j'obtiendrai une erreurError:Parceler: No @ParcelConstructor annotated constructor and no default empty bean constructor found.
Je pense (je ne l'ai pas testé) que je pourrais également rendre tous les paramètres du constructeur facultatifs et ajouter @JvmOverloads
mais cela a un effet secondaire que je dois vérifier toutes les propriétés de la classe si elles sont nulles ou non.
Mise à jour 2 :
C'est ce qui a fonctionné pour moi:
@Parcel
data class Valve(val size: Int? = null)
En bref Java doit avoir un constructeur vide par défaut. Une façon d'y parvenir est de faire comme ci-dessus - toutes les variables doivent avoir des valeurs par défaut.
Selon les documents, Parceler fonctionne par défaut avec les champs publics. Mais un Kotlin habituel data class
(comme dans votre exemple) est plutôt un "bean getter/setter traditionnel", car chaque propriété Kotlin est représentée par un champ privé et un getter/[setter].
TL; DR: Je pense que cela fonctionnera:
@Parcel(Serialization.BEAN)
data class Valve(val size: Int = 10)
Notez la valeur par défaut, elle permet à Kotlin de générer automatiquement un constructeur vide supplémentaire, qui est requis par la spécification Java Been).
Une autre façon serait de marquer le constructeur que nous avons déjà:
@Parcel(Serialization.BEAN)
data class Driver @ParcelConstructor constructor(val name: String)
Le document spécifique: https://github.com/johncarl81/parceler#gettersetter-serialization
Je sais que cette question a déjà une réponse, mais pour les futurs téléspectateurs qui ont également du mal à faire fonctionner Parceler avec des objets de données kotlin, j'ai écrit un nouveau processeur d'annotation pour générer le passe-partout Parcelable pour les classes de données Kotlin. Il est conçu pour réduire massivement le code passe-partout en rendant vos classes de données parcellables:
https://github.com/grandstaish/paperparcel
Utilisation:
Annotez votre classe de données avec @PaperParcel
, implémentez PaperParcelable
et ajoutez une instance statique JVM du CREATOR
généré, par exemple:
@PaperParcel
data class Example(
val test: Int,
...
) : PaperParcelable {
companion object {
@JvmField val CREATOR = PaperParcelExample.CREATOR
}
}
Maintenant, votre classe de données est Parcelable
et peut être transmise directement à un Bundle
ou Intent
Modifier: Mise à jour avec la dernière API
Ajoutez simplement le constructeur par défaut:
@Parcel
data class Valve(val size: Int) {
constructor() : this(0)
}
si vous utilisez Kotlin 1.1.4 ou supérieur, il est plus facile d'utiliser l'annotation @Parcelize
Pour ce faire, ajoutez d'abord ceci à build.gradle
Android {
//other codes
//for using latest experimental build of Android Extensions
androidExtensions {
experimental = true
}
}
Ensuite, changez votre classe comme ça
@Parcelize
data class Valve(val size: Int? = null) : Parcelable