Das kotlin-parcelize
-Plug-in
bietet eine
Implementierungsgenerator von Parcelable
.
Um Parcelable
zu unterstützen, füge das Gradle-Plug-in zu deinem
Datei build.gradle
der App:
Cool
plugins { id 'kotlin-parcelize' }
Kotlin
plugins { id("kotlin-parcelize") }
Wenn Sie eine Klasse mit @Parcelize
annotieren, wird eine Parcelable
-Implementierung
automatisch generiert, wie im folgenden Beispiel gezeigt:
import kotlinx.parcelize.Parcelize
@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable
Für @Parcelize
müssen alle serialisierten Attribute im
Primären Konstruktor. Das Plug-in gibt für jedes Attribut eine Warnung aus
mit einem im Klassentext deklarierten Sicherungsfeld. Außerdem können Sie nicht
@Parcelize
anwenden, wenn einige der primären Konstruktorparameter
und nicht auf Properties.
Wenn Ihre Klasse eine erweiterte Serialisierungslogik benötigt, schreiben Sie sie in eine Companion-Klasse:
@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
}
}
}
Unterstützte Typen
@Parcelize
unterstützt viele verschiedene Typen:
- Primitive Typen (und ihre Box-Versionen)
- Objekte und Enums
String
,CharSequence
Duration
Exception
Size
,SizeF
,Bundle
,IBinder
,IInterface
,FileDescriptor
SparseArray
,SparseIntArray
,SparseLongArray
,SparseBooleanArray
- Alle
Serializable
- (einschließlichDate
) undParcelable
-Implementierungen - Sammlungen aller unterstützten Typen:
List
(zugeordnet zuArrayList
),Set
(zugeordnet zuLinkedHashSet
),Map
(zugeordnet zuLinkedHashMap
)- Einige konkrete Implementierungen:
ArrayList
,LinkedList
,SortedSet
,NavigableSet
,HashSet
,LinkedHashSet
,TreeSet
,SortedMap
,NavigableMap
,HashMap
,LinkedHashMap
,TreeMap
ConcurrentHashMap
- Einige konkrete Implementierungen:
- Arrays aller unterstützten Typen
- Versionen aller unterstützten Typen, für die Nullwerte zulässig sind
Benutzerdefinierte Parceler
s
Wenn Ihr Typ nicht direkt unterstützt wird, können Sie einen Parceler
schreiben.
Zuordnungsobjekt.
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)
}
}
Sie können externe Pakete mit @TypeParceler
oder @WriteWith
anwenden
Anmerkungen:
// 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
Attribute aus Serialisierung überspringen
Wenn Sie eine bestimmte Property nicht parzellieren möchten, verwenden Sie die Anmerkung @IgnoredOnParcel
. Sie kann auch für Properties im Body einer Klasse verwendet werden, um Warnungen zu unterdrücken, dass die Property nicht serialisiert wird.
Mit @IgnoredOnParcel
annotierte Konstruktoreigenschaften müssen einen Standardwert haben
Wert.
@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
}
android.os.Parcel.writeValue zum Serialisieren einer Eigenschaft verwenden
Sie können einen Typ mit @RawValue
annotieren, damit Parcelize Parcel.writeValue
für diese Property verwendet.
@Parcelize
class MyClass(val external: @RawValue ExternalClass): Parcelable
Dies kann zur Laufzeit fehlschlagen, wenn der Wert der Eigenschaft nicht nativ von Android unterstützt.
Möglicherweise müssen Sie diese Anmerkung auch verwenden, wenn es keine anderen die Eigenschaft zu serialisieren.
Paketierung mit versiegelten Klassen und versiegelten Schnittstellen
Für die Paketerstellung ist eine Klasse erforderlich, die nicht abstrakt ist. Diese Einschränkung
nicht für abgedichtete Kurse. Wenn die Anmerkung @Parcelize
in einem
und muss für die abgeleiteten Klassen nicht wiederholt werden.
@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
Feedback
Falls Probleme mit dem Gradle-Plug-in kotlin-parcelize
auftreten, kannst du Folgendes tun:
Fehler melden