android - क्या कोटलिन के साथ एंड्रॉइड में पार्सलेबल डेटा कक्षाएं बनाने का एक सुविधाजनक तरीका है?




parcelable kotlin (8)

मैं वर्तमान में अपने जावा प्रोजेक्ट में उत्कृष्ट AutoParcel का उपयोग कर रहा हूं, जो पार्सलेबल कक्षाओं के निर्माण की सुविधा प्रदान करता है।

अब, कोटलिन, जिसे मैं अपनी अगली परियोजना के लिए विचार करता हूं, में डेटा वर्गों की यह अवधारणा है, जो स्वचालित रूप से बराबरी, हैशकोड औरString तरीकों को उत्पन्न करता है।

क्या एक सुविधाजनक तरीके से कोटलिन डेटा वर्ग को पार्सल करने का एक सुविधाजनक तरीका है (मैन्युअल तरीके लागू किए बिना)?


Kotlin ने अपने @Parcel एनोटेशन के साथ Android लानत में Parcelization की पूरी प्रक्रिया को आसान बना दिया है।

ऐसा करने के लिए

चरण 1. अपने ऐप मॉड्यूल ग्रेडेल में कोटलिन एक्सटेंशन जोड़ें

चरण 2। प्रयोगात्मक जोड़ें = सही क्योंकि यह सुविधा अब भी प्रयोग में है।

AndroidExtensions {प्रयोगात्मक = सच}

चरण 3. @Parcel के साथ डेटा वर्ग की घोषणा करें

Here @Parcel उपयोग पर एक सरल उदाहरण है


आप इस प्लगइन की कोशिश कर सकते हैं:

android-parcelable-intellij-plugin-kotlin

यह आपको कोटलिन के डेटा वर्ग के लिए एंड्रॉइड पार्सलेबल बॉयलरप्लेट कोड उत्पन्न करने में मदद करता है। और यह अंत में इस तरह दिखता है:

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 की कोशिश की है? यह एक एनोटेशन प्रोसेसर है जो स्वचालित रूप से आपके लिए एंड्रॉइड Parcelable बॉयलरप्लेट कोड उत्पन्न करता है।

उपयोग:

@PaperParcel साथ अपना डेटा वर्ग एनोटेट करें, @PaperParcel लागू PaperParcelable , और PaperParcelable किए गए PaperParcelable जेवीएम स्थिर उदाहरण को जोड़ें:

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

अब आपका डेटा वर्ग Parcelable और इसे सीधे एक Bundle या Intent पारित किया जा सकता है

संपादित करें: नवीनतम एपीआई के साथ अद्यतन करें


दुर्भाग्य से एक इंटरफ़ेस में एक वास्तविक क्षेत्र डालने के लिए कोटलिन में कोई रास्ता नहीं है, इसलिए आप इसे इंटरफ़ेस-एडेप्टर से मुफ्त में प्राप्त नहीं कर सकते हैं: data class Par : MyParcelable

आप प्रतिनिधिमंडल को देख सकते हैं, लेकिन यह फ़ील्ड्स, AFAIK के साथ मदद नहीं करता है: https://kotlinlang.org/docs/reference/delegation.html

तो एकमात्र विकल्प जो मैं देख रहा हूं वह Parcelable.Creator लिए एक कपड़े का कार्य है, जो स्पष्ट है।


मैं किसी के मदद करने के मामले में अपना रास्ता छोड़ दूंगा।

मैं क्या करूँ मैं एक सामान्य 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()) } }
}

जो मुझे उस बॉयलरप्लेट ओवरराइड से छुटकारा दिलाता है।


मैं सिर्फ https://github.com/johncarl81/parceler lib का उपयोग करना पसंद करता हूं

@Parcel(Parcel.Serialization.BEAN)
data class MyClass(val value)

एंड्रॉइड स्टूडियो और कोटलिन प्लगइन का उपयोग करते हुए, मैंने अपने पुराने जावा Parcelable को बिना किसी अतिरिक्त प्लगइन्स के कन्वर्ट करने का एक आसान तरीका पाया (यदि आप चाहते हैं कि एक ब्रांड नए data वर्ग को Parcelable में बदल दें, तो 4 वें कोड स्निपेट पर जाएं)।

मान लें कि आपके पास सभी Parcelable बॉयलर प्लेट के साथ एक Person वर्ग है:

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 कार्यान्वयन को अलग करने से शुरू करें, नंगे-हड्डियों, सादे, पुराने जावा ऑब्जेक्ट को छोड़ दें (गुण अंतिम और निर्माणकर्ता द्वारा निर्धारित किए जाने चाहिए):

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 का विकल्प 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 क्लास परिभाषा में जोड़ा जाता है।

टिप्पणियाँ:

  1. जावा Parcelable सीधे Parcelable बदलने की कोशिश करने से Parcelable प्लगइन ( 1.1.3 ) के वर्तमान संस्करण के साथ एक ही परिणाम नहीं होगा।
  2. मुझे कुछ अतिरिक्त घुंघराले ब्रेसिज़ को हटाने की आवश्यकता थी, जो वर्तमान Parcelable कोड जनरेटर परिचय देता है। एक मामूली बग होना चाहिए।

मुझे उम्मीद है कि यह टिप आपके लिए काम करेगी और साथ ही मेरे लिए भी।


कोई भी बॉयलरप्लेट कोड के साथ सबसे अच्छा तरीका है Smuggler ग्रेडल प्लगइन। बस आपको जरूरत है जैसे AutoParcelable इंटरफ़ेस को लागू करने की

data class Person(val name:String, val age:Int): AutoParcelable

और बस यही। सीलबंद कक्षाओं के लिए भी काम करता है। इसके अलावा यह प्लगइन सभी ऑटोपरेसेबल कक्षाओं के लिए संकलन समय सत्यापन प्रदान करता है।

UPD 17.08.2017 अब कोटलिन 1.1.4 और कोटलिन एंड्रॉइड एक्सटेंशन प्लगइन के साथ आप @Parcelize एनोटेशन का उपयोग कर सकते हैं। इस मामले में, ऊपर का उदाहरण दिखेगा:

@Parcelize class Person(val name:String, val age:Int): Parcelable

data संशोधक की कोई आवश्यकता नहीं है। सबसे बड़ा नकारात्मक पहलू यह है कि अब कोटलिन-एंड्रॉइड-एक्सटेंशन प्लगइन का उपयोग कर रहा है जिसमें बहुत सारे अन्य कार्य हैं जो अनावश्यक हो सकते हैं।





kotlin