Android 中Kotlin實現Parcelable

作爲android開發者都知道,開發中具備兩種序列化的操作,一個是Serializable,另一個是在Android中引入的Parcelable;從google官網的態度而言,Parcelable的效率更高。但是兩者的實現方式卻有很大區別,舉個例子


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)
        }
    }
}

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

後面在閱讀官方文檔的時候,發現Percelable也有了簡單的方式,而且官方也是推薦使用 Percelable,所以還是更改了使用習慣,而且,新的方式也很簡單點擊跳轉

1.Parcelable 實現生成器

首先引入組件

plugins {
    id 'kotlin-parcelize'
}

實現類主體結構

import kotlinx.parcelize.Parcelize

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

2.自定義序列化邏輯

有的同學就會問了,如果我想自己寫序列化和反序列化邏輯呢?當然也有辦法,就是在類內部實現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 支持的類型

應該說大部分的類型就是支持,但是如果真遇到了某個類型不被支持,但是開發者就是想要序列化,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

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


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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章