Le plug-in kotlin-parcelize
fournit un générateur d'implémentation Parcelable
.
Pour inclure la compatibilité avec Parcelable
, ajoutez le plug-in Gradle au fichier build.gradle
de votre application :
Groovy
plugins { id 'kotlin-parcelize' }
Kotlin
plugins { id("kotlin-parcelize") }
Lorsque vous annotez une classe avec @Parcelize
, une implémentation Parcelable
est automatiquement générée, comme illustré dans l'exemple suivant :
import kotlinx.parcelize.Parcelize
@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable
@Parcelize
nécessite que toutes les propriétés sérialisées soient déclarées dans le constructeur principal. Le plug-in émet un avertissement sur chaque propriété avec un champ de support déclaré dans le corps de la classe. De plus, vous ne pouvez pas appliquer @Parcelize
si certains paramètres du constructeur principal ne sont pas des propriétés.
Si votre classe nécessite une logique de sérialisation plus avancée, écrivez-la dans une classe compagnon :
@Parcelize
data class User(val firstName: String, val lastName: String, val age: Int) : Parcelable {
private companion object : Parceler<User> {
override fun User.write(parcel: Parcel, flags: Int) {
// Custom write implementation
}
override fun create(parcel: Parcel): User {
// Custom read implementation
}
}
}
Types acceptés
@Parcelize
accepte un large éventail de types :
- Types primitifs (et leurs versions encapsulées)
- Objets et énumérations
String
,CharSequence
Duration
Exception
Size
,SizeF
,Bundle
,IBinder
,IInterface
,FileDescriptor
SparseArray
,SparseIntArray
,SparseLongArray
,SparseBooleanArray
- Toutes les implémentations
Serializable
(y comprisDate
) etParcelable
- Les collections de tous les types compatibles :
List
(mappé surArrayList
),Set
(mappé surLinkedHashSet
),Map
(mappé surLinkedHashMap
)- Plusieurs implémentations concrètes sont également possibles :
ArrayList
,LinkedList
,SortedSet
,NavigableSet
,HashSet
,LinkedHashSet
,TreeSet
,SortedMap
,NavigableMap
,HashMap
,LinkedHashMap
,TreeMap
,ConcurrentHashMap
- Plusieurs implémentations concrètes sont également possibles :
- Tableaux de tous les types compatibles
- Versions nullable de tous les types compatibles
Parceler
personnalisés
Si votre type n'est pas directement pris en charge, vous pouvez écrire un objet de mappage Parceler
.
class ExternalClass(val value: Int)
object ExternalClassParceler : Parceler<ExternalClass> {
override fun create(parcel: Parcel) = ExternalClass(parcel.readInt())
override fun ExternalClass.write(parcel: Parcel, flags: Int) {
parcel.writeInt(value)
}
}
Vous pouvez appliquer des Parceler externes à l'aide d'annotations @TypeParceler
ou @WriteWith
:
// Class-local parceler
@Parcelize
@TypeParceler<ExternalClass, ExternalClassParceler>()
class MyClass(val external: ExternalClass) : Parcelable
// Property-local parceler
@Parcelize
class MyClass(@TypeParceler<ExternalClass, ExternalClassParceler>() val external: ExternalClass) : Parcelable
// Type-local parceler
@Parcelize
class MyClass(val external: @WriteWith<ExternalClassParceler>() ExternalClass) : Parcelable
Ignorer les propriétés de la sérialisation
Si vous ne souhaitez pas que certains biens soient morcelés, utilisez la méthode
Annotation @IgnoredOnParcel
. Il peut également être utilisé sur les propriétés d'une
corps de la classe pour mettre sous silence les avertissements indiquant que la propriété n'est pas sérialisée.
Les propriétés de constructeur annotées avec @IgnoredOnParcel
doivent avoir une valeur par défaut
.
@Parcelize
class MyClass(
val include: String,
// Don't serialize this property
@IgnoredOnParcel val ignore: String = "default"
): Parcelable {
// Silence a warning
@IgnoredOnParcel
val computed: String = include + ignore
}
Utiliser android.os.Parcel.writeValue pour sérialiser une propriété
Vous pouvez annoter un type avec @RawValue
pour que Parcelize l'utilise.
Parcel.writeValue
pour cette propriété.
@Parcelize
class MyClass(val external: @RawValue ExternalClass): Parcelable
Cette opération peut échouer au moment de l'exécution si la valeur de la propriété n'est pas compatible de manière native avec Android.
La fonctionnalité Parcelize peut également vous obliger à utiliser cette annotation lorsqu'il n'existe aucune autre moyen de sérialiser la propriété.
Parcéliser à l'aide de classes scellées et d'interfaces scellées
Avec Parcelize, une classe de segmentation ne doit pas être abstraite. Cette limite ne fait
ne sont pas conservées
pour les classes scellées. Lorsque l'annotation @Parcelize
est utilisée sur une
scellée, il n'est pas nécessaire de la répéter pour les classes dérivées.
@Parcelize
sealed class SealedClass: Parcelable {
class A(val a: String): SealedClass()
class B(val b: Int): SealedClass()
}
@Parcelize
class MyClass(val a: SealedClass.A, val b: SealedClass.B, val c: SealedClass): Parcelable
Commentaires
Si vous rencontrez des problèmes avec le plug-in Gradle kotlin-parcelize
, vous veuillez signaler un bug.