web-dev-qa-db-ja.com

シリアライゼーション用のコンストラクターを備えたKotlinデータクラスでのParcelerの使用

各フィールドに_@ParcelProperty_アノテーションを使用せずに、シリアル化のためにKotlinデータクラスとコンストラクターで Parceler を使用する方法はありますか?

私がこのようなライブラリを試して使用すると:

_@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_を追加することもできると思いますが、nullまたはない。

更新2
これが私にとってうまくいきました:

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

つまり、生成されたJavaクラスにはデフォルトの空のコンストラクタが必要です。これを達成する1つの方法は、上記のようにすることです-すべての変数にデフォルト値が必要です。

23
Martynas Jurkus

ドキュメントによると、Parcelerはデフォルトでパブリックフィールドで動作します。しかし、通常のKotlin data class(例のように)は、すべてのKotlinプロパティがプライベートフィールドとゲッター/ [セッター]で表されるため、むしろ「従来のゲッター/セッターBean」です。

TL; DR:これはうまくいくと思います:

@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

28
voddan

この質問にはすでに回答がありますが、Parcelerでkotlinデータオブジェクトを操作するのに苦労している将来の視聴者のために、KotlinデータクラスのParcelableボイラープレートを生成する新しい注釈プロセッサを作成しました。データクラスをParcelableにする際の定型コードを大幅に削減するように設計されています。

https://github.com/grandstaish/paperparcel

用途:

データクラスに@PaperParcelで注釈を付け、PaperParcelableを実装し、生成されたCREATORのJVM静的インスタンスを追加します。例:

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

これで、データクラスはParcelableになり、BundleまたはIntentに直接渡すことができます

編集:最新のAPIで更新

10

デフォルトのコンストラクタを追加するだけです:

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

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
2
Radesh