Android 中Kotlin實現(xiàn)Parcelable

作為android開發(fā)者都知道,開發(fā)中具備兩種序列化的操作,一個是Serializable,另一個是在Android中引入的Parcelable;從google官網(wǎng)的態(tài)度而言,Parcelable的效率更高。但是兩者的實現(xiàn)方式卻有很大區(qū)別,舉個例子

image.png

Serializable

class Human:Serializable {
    
}

Parcelable

class Person() :Parcelable {

    var name:String = ""
    var age:Int = 0

    constructor(parcel: Parcel) : this() {
    }

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeString(name)
        dest.writeInt(age)
    }

    companion object CREATOR : Parcelable.Creator<Person> {
        override fun createFromParcel(parcel: Parcel): Person {
            val person = Person()
            person.name = parcel.readString()?:""
            person.age = parcel.readInt()?:0
            return person
        }

        override fun newArray(size: Int): Array<Person?> {
            return arrayOfNulls(size)
        }
    }
}

發(fā)現(xiàn)什么問題了嗎?沒錯,Percelable的實現(xiàn)方式更復(fù)雜,Serializable只需實現(xiàn)一個接口就完成了,管他那么多,Serializable就完事了(這也是我至今都喜歡Serializable的原因)

后面在閱讀官方文檔的時候,發(fā)現(xiàn)Percelable也有了簡單的方式,而且官方也是推薦使用 Percelable,所以還是更改了使用習(xí)慣,而且,新的方式也很簡單點擊跳轉(zhuǎn)

image.png

1.Parcelable 實現(xiàn)生成器

首先引入組件

plugins {
    id 'kotlin-parcelize'
}

實現(xiàn)類主體結(jié)構(gòu)

import kotlinx.parcelize.Parcelize

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

2.自定義序列化邏輯

有的同學(xué)就會問了,如果我想自己寫序列化和反序列化邏輯呢?當(dāng)然也有辦法,就是在類內(nèi)部實現(xiàn)write和create方法

@Parcelize
data class User(val firstName: String, val lastName: String, val age: Int) : Parcelable {
    private companion object : Parceler<User> {
        override fun User.write(parcel: Parcel, flags: Int) {
            // Custom write implementation
        }

        override fun create(parcel: Parcel): User {
            // Custom read implementation
        }
    }
}

3.Parcelable 支持的類型

應(yīng)該說大部分的類型就是支持,但是如果真遇到了某個類型不被支持,但是開發(fā)者就是想要序列化,Parcelable也有自定義的方法,就是

class ExternalClass(val value: Int)

object ExternalClassParceler : Parceler<ExternalClass> {
    override fun create(parcel: Parcel) = ExternalClass(parcel.readInt())

    override fun ExternalClass.write(parcel: Parcel, flags: Int) {
        parcel.writeInt(value)
    }
}

使用也很方便

// Class-local parceler
@Parcelize
@TypeParceler<ExternalClass, ExternalClassParceler>()
class MyClass(val external: ExternalClass) : Parcelable

// Property-local parceler
@Parcelize
class MyClass(@TypeParceler<ExternalClass, ExternalClassParceler>() val external: ExternalClass) : Parcelable

// Type-local parceler
@Parcelize
class MyClass(val external: @WriteWith<ExternalClassParceler>() ExternalClass) : Parcelable

簡單也易上手,但是也溫馨提醒,大量數(shù)據(jù)跨組件傳遞,會存在為以下情況


image.png

因為intent中能帶的數(shù)據(jù)有上限(這個根據(jù)不同的android廠商而異),建議這時候試用viewmodel來做數(shù)據(jù)傳遞

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容