저는 현재 Parcelable 클래스 생성을 용이하게하는 Java 프로젝트에서 우수한 AutoParcel 을 사용하고 있습니다.
이제 다음 프로젝트에서 고려할 Kotlin에는 equals, hashCode 및 toString 메서드를 자동으로 생성하는 이러한 데이터 클래스 개념이 있습니다.
메서드를 수동으로 구현하지 않고 편리한 방법으로 Parcelable 데이터 클래스를 Parcelable로 만드는 편리한 방법이 있습니까?
저는 현재 Parcelable 클래스 생성을 용이하게하는 Java 프로젝트에서 우수한 AutoParcel 을 사용하고 있습니다.
이제 다음 프로젝트에서 고려할 Kotlin에는 equals, hashCode 및 toString 메서드를 자동으로 생성하는 이러한 데이터 클래스 개념이 있습니다.
메서드를 수동으로 구현하지 않고 편리한 방법으로 Parcelable 데이터 클래스를 Parcelable로 만드는 편리한 방법이 있습니까?
답변:
Kotlin 1.1.4 가 출시 되었습니다.
이제 Android 확장 플러그인에 자동 Parcelable 구현 생성기가 포함됩니다. 기본 생성자에서 직렬화 된 속성을 선언하고 @Parcelize 주석을 추가하면 writeToParcel () / createFromParcel () 메서드가 자동으로 생성됩니다.
@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
따라서 모듈의 build.gradle에 이것을 추가하여 활성화해야합니다 .
apply plugin: 'org.jetbrains.kotlin.android.extensions'
android {
androidExtensions {
experimental = true
}
}
this calss implements Parcelable but does not provice CREATOR field
합니다. 답변이 충분합니까 (전체)?
@SuppressLint("ParcelCreator")
보푸라기 경고를 제거 하는 데 사용할 수 있습니다 .
이 플러그인을 사용해 볼 수 있습니다.
android-parcelable-intellij-plugin-kotlin
kotlin의 데이터 클래스에 대한 Android Parcelable 상용구 코드를 생성하는 데 도움이됩니다. 그리고 마침내 다음과 같이 보입니다.
data class Model(var test1: Int, var test2: Int): Parcelable {
constructor(source: Parcel): this(source.readInt(), source.readInt())
override fun describeContents(): Int {
return 0
}
override fun writeToParcel(dest: Parcel?, flags: Int) {
dest?.writeInt(this.test1)
dest?.writeInt(this.test2)
}
companion object {
@JvmField final val CREATOR: Parcelable.Creator<Model> = object : Parcelable.Creator<Model> {
override fun createFromParcel(source: Parcel): Model{
return Model(source)
}
override fun newArray(size: Int): Array<Model?> {
return arrayOfNulls(size)
}
}
}
}
PaperParcel 을 사용해 보셨습니까 ? Android Parcelable
상용구 코드를 자동으로 생성하는 주석 프로세서입니다 .
용법:
생성 된 JVM 정적 인스턴스를 사용 하여 데이터 클래스에 주석을 달고 @PaperParcel
구현 PaperParcelable
하고 추가합니다 CREATOR
. 예 :
@PaperParcel
data class Example(
val test: Int,
...
) : PaperParcelable {
companion object {
@JvmField val CREATOR = PaperParcelExample.CREATOR
}
}
이제 데이터 클래스는 Parcelable
과에 직접 전달할 수있는 Bundle
나Intent
편집 : 최신 API로 업데이트
최고의 와 방법은 없는 상용구 전혀 코드는 밀수의 Gradle을 플러그인. 필요한 것은 AutoParcelable 인터페이스를 구현하는 것입니다.
data class Person(val name:String, val age:Int): AutoParcelable
그리고 그게 전부입니다. 봉인 된 수업에서도 작동합니다. 또한이 플러그인은 모든 AutoParcelable 클래스에 대한 컴파일 시간 유효성 검사를 제공합니다.
UPD 17.08.2017 이제 Kotlin 1.1.4 및 Kotlin Android 확장 플러그인에서@Parcelize
주석을 사용할 수 있습니다 . 이 경우 위의 예는 다음과 같습니다.
@Parcelize class Person(val name:String, val age:Int): Parcelable
data
수정자가 필요 없습니다 . 현재 가장 큰 단점은 불필요 할 수있는 다른 많은 기능이있는 kotlin-android-extensions 플러그인을 사용하는 것입니다.
사용하여 안드로이드 스튜디오 와 코 틀린의 플러그인을, 나는 나의 오래된 자바로 변환하는 쉬운 방법을 발견 Parcelable
들과 별도의 플러그인 (당신이 원하는 모든 새로운 설정하는 경우 data
로 클래스를 Parcelable
, 제 4 코드로 건너을).
Person
모든 Parcelable
보일러 플레이트 가있는 클래스 가 있다고 가정 해 보겠습니다 .
public class Person implements Parcelable{
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
private final String firstName;
private final String lastName;
private final int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
protected Person(Parcel in) {
firstName = in.readString();
lastName = in.readString();
age = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeInt(age);
}
@Override
public int describeContents() {
return 0;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
}
Parcelable
구현 을 제거하고 기본적이고 평범한 오래된 Java 객체 (속성은 최종 속성이어야하며 생성자가 설정해야 함)를 남겨 둡니다 .
public class Person {
private final String firstName;
private final String lastName;
private final int age;
public Person(String firstName, String lastName, int age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
}
그런 다음 Code > Convert Java file to Kotlin File
옵션이 마법을 사용 하도록합니다 .
class Person(val firstName: String, val lastName: String, val age: Int)
이것을 data
클래스 로 변환하십시오 .
data class Person(val firstName: String, val lastName: String, val age: Int)
그리고 마지막으로 이것을 Parcelable
다시 로 바꿔 봅시다 . 클래스 이름에 마우스를 가져 가면 Android Studio에 Add Parcelable Implementation
. 결과는 다음과 같습니다.
data class Person(val firstName: String, val lastName: String, val age: Int) : Parcelable {
constructor(parcel: Parcel) : this(
parcel.readString(),
parcel.readString(),
parcel.readInt()
)
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(firstName)
parcel.writeString(lastName)
parcel.writeInt(age)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<Person> {
override fun createFromParcel(parcel: Parcel): Person {
return Person(parcel)
}
override fun newArray(size: Int): Array<Person?> {
return arrayOfNulls(size)
}
}
}
보시다시피 Parcelable
구현은 data
클래스 정의에 추가 된 자동 생성 코드 입니다.
노트:
Parcelable
를 Kotlin으로 직접 변환하려고 하면 현재 버전의 Kotlin 플러그인 ( 1.1.3
) 과 동일한 결과가 생성되지 않습니다 .Parcelable
코드 생성기에서 소개 하는 추가 중괄호를 제거해야했습니다 . 사소한 버그 여야합니다.이 팁이 저와 마찬가지로 당신에게도 효과가 있기를 바랍니다.
누군가에게 도움이 될 수있는 경우를 대비하여 내 방식을 떠날 것입니다.
내가하는 일은 일반 Parcelable
interface DefaultParcelable : Parcelable {
override fun describeContents(): Int = 0
companion object {
fun <T> generateCreator(create: (source: Parcel) -> T): Parcelable.Creator<T> = object: Parcelable.Creator<T> {
override fun createFromParcel(source: Parcel): T = create(source)
override fun newArray(size: Int): Array<out T>? = newArray(size)
}
}
}
inline fun <reified T> Parcel.read(): T = readValue(T::class.javaClass.classLoader) as T
fun Parcel.write(vararg values: Any?) = values.forEach { writeValue(it) }
그런 다음 다음과 같은 구획을 만듭니다.
data class MyParcelable(val data1: Data1, val data2: Data2) : DefaultParcelable {
override fun writeToParcel(dest: Parcel, flags: Int) { dest.write(data1, data2) }
companion object { @JvmField final val CREATOR = DefaultParcelable.generateCreator { MyParcelable(it.read(), it.read()) } }
}
그러면 상용구 재정의가 제거됩니다.
예 :
@Parcelize
data class Item(
var imageUrl: String,
var title: String,
var description: Category
) : Parcelable
안타깝게도 Kotlin에서는 인터페이스에 실제 필드를 넣을 수있는 방법이 없으므로 인터페이스 어댑터에서 무료로 상속 할 수 없습니다.
data class Par : MyParcelable
위임을 볼 수는 있지만 필드에는 도움이되지 않습니다. AFAIK : https://kotlinlang.org/docs/reference/delegation.html
그래서 제가 보는 유일한 옵션은의 패브릭 함수입니다 Parcelable.Creator
.
나는 https://github.com/johncarl81/parceler lib를 사용하는 것을 선호합니다.
@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)
@Parcelize
주석 을 사용하여 할 수 있습니다 . 자동 Parcelable 구현 생성기입니다.
먼저 모듈의 build.gradle에이를 추가하여 활성화해야합니다.
apply plugin: 'org.jetbrains.kotlin.android.extensions'
기본 생성자에서 직렬화 된 속성을 선언하고 @Parcelize
주석을 추가하면 writeToParcel()
/ createFromParcel()
메서드가 자동으로 생성됩니다.
@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable
당신 DONT의 필요성이 추가 experimental = true
내부 androidExtensions
블록을.
Kotlin은 @Parcel 주석을 사용하여 Android에서 Parcelization의 전체 프로세스를 쉽게 만들었습니다.
하기 위해서
1 단계. 앱 모듈 Gradle에 Kotlin 확장 프로그램 추가
2 단계. 이 기능은 여전히 Gradle에서 실험 중이므로 Experiment = true를 추가합니다.
androidExtensions {실험적 = true}
3 단계. @Parcel을 사용하여 데이터 클래스 발표
다음 은 @Parcel 사용에 대한 간단한 예입니다.
플러그인이 있지만 Kotlin이 진화함에 따라 항상 업데이트되는 것은 아닙니다 : https://plugins.jetbrains.com/plugin/8086
대안 :Parcelable
및 목록을
사용하는 사용자 지정 데이터 클래스의 작업 예제가 있습니다 .
Parcelable with Lists를 사용하는 데이터 클래스 :
도움이 되었기를 바랍니다.