কোটলিনের সাথে অ্যান্ড্রয়েডে পার্সেবল ডেটা ক্লাস তৈরি করার কোনও সুবিধাজনক উপায় আছে কি?


116

আমি বর্তমানে আমার জাভা প্রকল্পে দুর্দান্ত অটো পার্সেল ব্যবহার করছি , যা পার্সেবল ক্লাস তৈরির সুবিধার্থে।

এখন, কোটলিন, যা আমি আমার পরবর্তী প্রকল্পের জন্য বিবেচনা করি, এটি ডেটা ক্লাসগুলির এই ধারণাটি ধারণ করে, যা স্বয়ংক্রিয়ভাবে সমান, হ্যাশকোড এবং টু স্ট্রিং পদ্ধতি তৈরি করে।

কোনও কোটলিন ডেটা ক্লাসকে কোনও সুবিধাজনক উপায়ে (পদ্ধতিগুলি নিজে প্রয়োগ না করে) পার্সেবল করার কোনও সুবিধাজনক উপায় আছে কি?


2
আপনি কি ক্যাপ্ট চেষ্টা করেছেন? ব্লগ.জেটব্রিনস.কোটলিন
সের্গেই মাশকভ

আপনি কি কোটলিনের সাথে অটোপার্সেল ব্যবহার করবেন? আমি এটি সম্পর্কে ভেবেছিলাম, তবে যদি ভাষাতে পার্সেবল ডেটা ক্লাস করার কোনও উপায় ছিল, তবে এটি সুন্দর হবে। বিশেষত কোটলিন ব্যবহারের একটি বিশাল অংশ বিবেচনা করে আসবে অ্যান্ড্রয়েড অ্যাপ্লিকেশনগুলি।
থ্যালসেমেলো

উত্তর:


187

কোটলিন 1.1.4 আউট আছে

অ্যান্ড্রয়েড এক্সটেনশানস প্লাগইনে এখন একটি স্বয়ংক্রিয় পার্সেবল বাস্তবায়ন জেনারেটর অন্তর্ভুক্ত। প্রাথমিক কনস্ট্রাক্টরে সিরিয়ালযুক্ত বৈশিষ্ট্যগুলি ঘোষণা করুন এবং একটি @ পার্সেলাইজ টিকা যুক্ত করুন, এবং লিখন টো পার্সেল () / createFromParcel () পদ্ধতিগুলি স্বয়ংক্রিয়ভাবে তৈরি হবে:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable

সুতরাং আপনাকে এগুলি আপনার মডিউলের বিল্ড.gradle এ যুক্ত করতে সক্ষম করতে হবে :

apply plugin: 'org.jetbrains.kotlin.android.extensions'

android {
    androidExtensions {
        experimental = true
    }
}

2
যারা এটি পরীক্ষা করে দেখতে চান তাদের জন্য: blog.jetbrains.com/kotlin/2017/08/kotlin-1-1-4-is-out
thalesmello

3
কেন এটি আর ডেটা ক্লাস হয় না। এই উদাহরণটি কি কেবল এটি দেখানোর জন্যই যে কোনও জেনেরিক কোটলিন শ্রেণিতে এটি প্রয়োগ করা যেতে পারে?
নিতিন জৈন

10
সংকলক অভিযোগ this calss implements Parcelable but does not provice CREATOR field। আপনার উত্তর যথেষ্ট (পূর্ণ)?

1
@ মুর্ট আপনি কি সফলভাবে পার্সেবল ব্যবহার করেছেন? আমি প্রস্তুতকারকের কারণে সংকলনের ত্রুটির মুখোমুখি হয়েছি
শীর্ষ

4
আপনি @SuppressLint("ParcelCreator")লিন্টের সতর্কতা থেকে মুক্তি পেতে ব্যবহার করতে পারেন ।
ডাচ মাস্টার্স

47

আপনি এই প্লাগইন চেষ্টা করতে পারেন:

অ্যান্ড্রয়েড-parcelable-intellij-প্লাগইন-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)
            }
        }
    }
}

19

আপনি কি পেপারপার্সেল চেষ্টা করেছেন ? এটি একটি এনোটেশন প্রসেসর যা স্বয়ংক্রিয়ভাবে আপনার জন্য অ্যান্ড্রয়েড Parcelableবয়লারপ্লেট কোড উত্পন্ন করে ।

ব্যবহার:

উত্পন্ন উত্সের একটি JVM স্ট্যাটিক উদাহরণ সহ আপনার ডেটা ক্লাসটি টিকে টানুন @PaperParcel, প্রয়োগ PaperParcelableকরুন এবং যুক্ত করুন CREATOR:

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

এখন আপনার ডেটা ক্লাস হয় Parcelableএবং সরাসরি একটি Bundleবা এ পাস করা যেতে পারেIntent

সম্পাদনা করুন: সর্বশেষ এপিআই সহ আপডেট করুন


আইডিই এখন বলেছে "অন্যান্য ক্লাসের ডেটা ক্লাসের উত্তরাধিকার নিষিদ্ধ"। আমি মনে করি পেপারপার্সেল ডেটা ক্লাসের সাথে আর ব্যবহার করা যাবে না ...
ম্যাসিমো

তারা কখনই অন্য শ্রেণীর কাছ থেকে উত্তরাধিকারী হতে পারেনি, তবে তারা ইন্টারফেসগুলি প্রয়োগ করতে পারে (যেমন পেপারপার্সেবল)
ব্র্যাডলে ক্যাম্পবেল

1
@ ব্র্যাডলি ক্যাম্পবেল এটি আমাকে এই লাইনে একটি ত্রুটি দেয় জেভিএমফিল্ড ভাল CREATOR = পেপারপার্সেল উদাহরণ।ক্রেটিটর পেপারপার্সেল নমুনা শ্রেণি তৈরি করতে পারে না
মিঃজি

19

আপনার কোটলিন ডেটা ক্লাসের ডেটা কীওয়ার্ডটি ক্লিক করুন, তারপরে Alt + enter টিপুন, প্রথম বিকল্পটি নির্বাচন করে নির্বাচন করুন "Add Parceable Implementation"


2
আমি এই পদ্ধতিটি ব্যবহার করেছি, তবে এতে বেশ কয়েকটি সমস্যা রয়েছে। কখনও কখনও এটি ক্ষেত্রটি না থাকলে এর parcel.read...সাথে প্রতিস্থাপন করে । আপনি যদি কোনও শ্রেণীর ভিতরে ব্যবহার করেন তবে আপনার বাস্তবায়ন সমস্যা হয়ে দাঁড়ায়। সুতরাং আমি গৃহীত উত্তরের দিকে ফিরেছি । TODOval/varList@Parcelize
কুলমাইন্ড

16

সেরা সাথে পথ কোন boilerplate, এ সব কোড চোরাকারবারি gradle প্লাগইন। আপনার কেবলমাত্র অটোপ্যারসেসেবল ইন্টারফেসের মতো প্রয়োগ করা দরকার

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

এবং যে সব. সিল করা ক্লাসগুলির জন্যও কাজ করে। এছাড়াও এই প্লাগইনটি সমস্ত অটোপ্রেসেসযোগ্য ক্লাসগুলির জন্য সংকলনের সময় বৈধতা সরবরাহ করে।

ইউপিডি 17.08.2017 এখন কোটলিন 1.1.4 এবং কোটলিন অ্যান্ড্রয়েড এক্সটেনশান প্লাগইনের সাহায্যে আপনি @Parcelizeটিকা ব্যবহার করতে পারেন । এক্ষেত্রে উপরের উদাহরণটি দেখতে পাবেন:

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

dataসংশোধক প্রয়োজন হয় না । সবচেয়ে বড় ক্ষয়ক্ষতি, আপাতত, কোটলিন-অ্যান্ড্রয়েড-এক্সটেনশান প্লাগইন ব্যবহার করা হচ্ছে যাতে অপ্রয়োজনীয় হতে পারে এমন আরও অনেক কার্য রয়েছে।


6

অ্যান্ড্রয়েড স্টুডিও এবং কোটলিন প্লাগইন ব্যবহার করে , আমি আমার পুরানো জাভা Parcelableগুলি কোনও অতিরিক্ত প্লাগইন ছাড়াই রূপান্তর করার একটি সহজ উপায় খুঁজে পেয়েছি (যদি আপনি চান তবে একটি ব্র্যান্ডের নতুন dataশ্রেণিকে একটিতে রূপান্তর করাParcelable করতে, ৪ র্থ কোড স্নিপেটে চলে যান)।

ধরা যাক আপনার 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একটি খালি হাড়, সরল, পুরাতন জাভা অবজেক্ট (সম্পত্তি চূড়ান্ত হওয়া উচিত এবং নির্মাণকারীর দ্বারা সেট করা উচিত) রেখে বাস্তবায়নটি ছড়িয়ে দিয়ে শুরু করুন :

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আবার পরিবর্তন করুন। ক্লাসের নামটি হোভার করুন এবং অ্যান্ড্রয়েড স্টুডিওতে আপনাকে বিকল্পটি দেওয়া উচিত 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 সরাসরি কোটলিনে রূপান্তরিত করার চেষ্টা করা কোটলিন প্লাগইন ( 1.1.3) এর বর্তমান সংস্করণ সহ একই ফলাফল তৈরি করবে না ।
  2. বর্তমান Parcelableকোড জেনারেটরের পরিচয় করিয়ে দিয়ে আমাকে কিছু অতিরিক্ত কোঁকড়া ধনুর্বন্ধনী অপসারণ করতে হয়েছিল। অবশ্যই একটি ছোটখাটো বাগ থাকতে হবে।

আমি আশা করি এই টিপটি আপনার পক্ষে যেমন কাজ করেছে তেমনি এটি আমার পক্ষেও হয়েছে।


4

এটি কারওর পক্ষে সহায়তা করার ক্ষেত্রে আমি আমার কাজটি ছেড়ে দেব।

আমি যা করি তা আমার একটি জেনেরিক 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()) } }
}

যা আমাকে সেই বয়লারপ্লেট ওভাররাইড থেকে মুক্তি দেয়।


4
  • আপনার মডেল / ডেটা ক্লাসের শীর্ষে @ পার্সেলিজ টীকাটি ব্যবহার করুন
  • কোটলিনের সর্বশেষতম সংস্করণ ব্যবহার করুন
  • আপনার অ্যাপ্লিকেশন মডিউলে কোটলিন অ্যান্ড্রয়েড এক্সটেনশনের সর্বশেষতম সংস্করণ ব্যবহার করুন

উদাহরণ:

@Parcelize
data class Item(
    var imageUrl: String,
    var title: String,
    var description: Category
) : Parcelable

3

দুর্ভাগ্যক্রমে কোনও ইন্টারফেসে আসল ক্ষেত্র স্থাপনের জন্য কোটলিনের কোনও উপায় নেই, সুতরাং আপনি এটিকে কোনও ইন্টারফেস-অ্যাডাপ্টারের কাছ থেকে নিখরচায় অধিকার করতে পারবেন না: data class Par : MyParcelable

আপনি প্রতিনিধিদের দিকে নজর রাখতে পারেন, তবে এটি ক্ষেত্রগুলির সাথে কোনও সহায়তা করে না, এএফাইক: https://kotlinlang.org/docs/reference/delegation.html

সুতরাং আমি দেখতে পাচ্ছি একমাত্র বিকল্প হ'ল এটি একটি ফ্যাব্রিক ফাংশন Parcelable.Creator, যা এক ধরণের স্পষ্ট।


2

আমি কেবল https://github.com/johncarl81/parceler lib এর সাহায্যে ব্যবহার করতে পছন্দ করি

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

এই দেয় ত্রুটি "ক্লাস 'MyClass' বিমূর্ত নয় এবং বিমূর্ত সদস্য প্রকাশ্য বিমূর্ত মজা writeToParcel বাস্তবায়ন না (DEST: পুলিন্দা !, পতাকা: int): ইউনিট android.os.Parcelable সংজ্ঞায়িত
PhillyTheThrilly

2

আপনি @Parcelizeটীকাটি ব্যবহার করে এটি করতে পারেন । এটি একটি স্বয়ংক্রিয় পার্সেবল বাস্তবায়ন জেনারেটর।

প্রথমত, আপনাকে এগুলি আপনার মডিউলের বিল্ড.gradle এ যুক্ত করতে সক্ষম করতে হবে:

apply plugin: 'org.jetbrains.kotlin.android.extensions'

প্রাথমিক নির্মাত্রে সিরিয়ালযুক্ত বৈশিষ্ট্যগুলি ঘোষণা করুন এবং একটি @Parcelizeটীকা যুক্ত করুন এবং writeToParcel()/ createFromParcel()পদ্ধতিগুলি স্বয়ংক্রিয়ভাবে তৈরি হবে:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable

আপনি আত যোগ করতে হবে experimental = trueভিতরে androidExtensionsব্লক।


1

কোটলিন অ্যান্ড্রয়েড ড্যামে পার্সেলাইজেশনের পুরো প্রক্রিয়াটিকে তার @ পার্সেল টিকা দিয়ে সহজ করে তুলেছে।

এটা করতে

পদক্ষেপ 1. আপনার অ্যাপ্লিকেশন মডিউল গ্রেডে কোটলিন এক্সটেনশনগুলি যুক্ত করুন

পদক্ষেপ ২. পরীক্ষামূলক = সত্য যুক্ত করুন যেহেতু এই বৈশিষ্ট্যটি গ্রেডে এখনও পরীক্ষায় রয়েছে।

অ্যান্ড্রয়েড এক্সটেনশনগুলি {পরীক্ষামূলক = সত্য}

পদক্ষেপ 3. @ পার্সেল দিয়ে ডেটা ক্লাসটি অ্যানোনেট করুন

এখানে @ পার্সেল ব্যবহারের একটি সাধারণ উদাহরণ is


0

একটি প্লাগইন রয়েছে তবে কোটলিন যেভাবে বিকশিত হচ্ছে সেভাবে সর্বদা আপডেট হয় না: https://plugins.jetbrains.com/plugin/8086

বিকল্প: আমার কাছে কাস্টম ডেটা ক্লাস ব্যবহার Parcelableএবং তালিকাগুলির কাজ করার উদাহরণ রয়েছে :

তালিকা সহ পার্সেবল ব্যবহার করে ডেটা ক্লাস:

https://gist.github.com/juanchosaravia/0b61204551d4ec815bbf

আশা করি এটা সাহায্য করবে!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.