各フィールドに_@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つの方法は、上記のようにすることです-すべての変数にデフォルト値が必要です。
ドキュメントによると、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
この質問にはすでに回答がありますが、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で更新
デフォルトのコンストラクタを追加するだけです:
@Parcel
data class Valve(val size: Int) {
constructor() : this(0)
}
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