저는 현재 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
}
}
답변
이 플러그인을 사용해 볼 수 있습니다.
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)
}
}
}
}
답변
kotlin 데이터 클래스의 데이터 키워드를 클릭 한 다음 alt + Enter를 누르고 첫 번째 옵션을 선택하십시오. "Add Parceable Implementation"
답변
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()) } }
}
그러면 상용구 재정의가 제거됩니다.