Generator für Parcelable-Implementierungen

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ßlich Date) und Parcelable-Implementierungen
  • Sammlungen aller unterstützten Typen: List (zugeordnet zu ArrayList), Set (zugeordnet zu LinkedHashSet), Map (zugeordnet zu LinkedHashMap)
    • Einige konkrete Implementierungen: ArrayList, LinkedList, SortedSet, NavigableSet, HashSet, LinkedHashSet, TreeSet, SortedMap, NavigableMap, HashMap, LinkedHashMap, TreeMap ConcurrentHashMap
  • Arrays aller unterstützten Typen
  • Versionen aller unterstützten Typen, für die Nullwerte zulässig sind

Benutzerdefinierte Parcelers

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