美文网首页Android知识Android开发程序员
Kotlin中泛型的序列化Parcelable

Kotlin中泛型的序列化Parcelable

作者: 我爱吃栗子啊 | 来源:发表于2017-07-14 23:20 被阅读2098次

系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正。如果你觉得我的文章对你有用,欢迎关注我以及我的Kotlin专题,我们一起学习进步!

终于有一篇Kotlin文章不是沿袭了之前的笔记系列,这是尝试将Kotlin用到项目中遇到的第一个问题:如何将Kotlin中的泛型进行序列化?这个问题我们分两步解决:

  • 一般数据类(data class)的序列化
  • 泛型的序列化

一、一般数据类(data class)的序列化

这个问题在我之前的文章《Kotlin学习笔记(9)- 数据类》中提到过,这里再说一下,在kotlin中序列化的实现方法和java中的手动实现基本一致

data class PersonData(var name : String, var age : Int, val sex : String) : Parcelable{
    override fun writeToParcel(p0: Parcel?, p1: Int) {
        p0?.writeString(this.name)
        p0?.writeInt(this.age)
        p0?.writeString(this.sex)
    }

    override fun describeContents(): Int {
        return 0
    }

    constructor(source: Parcel) : this(source.readString(), source.readInt(), source.readString())

    companion object {
        @JvmField val CREATOR: Parcelable.Creator<PersonData> = object : Parcelable.Creator<PersonData> {
            override fun createFromParcel(source: Parcel): PersonData {
                return PersonData(source)
            }

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

值得一提的是,在我写《Kotlin学习笔记(9)- 数据类》的时候,也确实只能这么写。但是现在AS上已经有了自动序列化的插件:在AS的Settings中选择Plugins,然后搜索“Parcelable Code Generator(for kotlin)”,安装即可。相信很多朋友用过它的Andorid版,使用方法基本是一样的,使用效果如图:

效果图效果图

二、泛型的序列化

泛型就不必多说了,我在《Kotlin学习笔记(10)- 泛型》也详细的讲过了(这广告太自然了,哇咔咔),个人使用最多的场景应该就是处理服务器返回的结果了吧。如果恰巧这个结果模型需要在Activity间传递,那么是不是就要考虑泛型的序列化了呢?首先看看我是怎么实现的:

data class Resp<T: Parcelable>(var code: Int = 0,
                               var msg: String = "",
                               var data: T? = null)
    : Parcelable {

    val EMPTY = "empty"

    constructor(source: Parcel) : this() {
        code = source.readInt()
        msg = source.readString()
        val className = source.readString()
        data = if(className == EMPTY) null else source.readParcelable(Class.forName(className).getClassLoader())
    }

    fun classLoader() : ClassLoader {
        val type = javaClass.genericSuperclass
        val params = (type as ParameterizedType).actualTypeArguments
        return (params[0] as Class<T>).classLoader
    }

    override fun describeContents(): Int {
        return 0
    }

    override fun writeToParcel(dest: Parcel, flags: Int) {
        dest.writeInt(this.code)
        dest.writeString(this.msg)
        dest.writeString(if(this.data==null) EMPTY else this.data!!::class.java.name)
        dest.writeParcelable(this.data, flags)
    }

    companion object {

        @JvmField val CREATOR: Parcelable.Creator<Resp<Parcelable>> = object : Parcelable.Creator<Resp<Parcelable>> {
            override fun createFromParcel(source: Parcel): Resp<Parcelable> {
                return Resp<Parcelable>(source)
            }

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

要注意以下几点:

  1. 泛型T一定要显式的声明可序列化,也就是我的泛型类型<T: Parcelable>

  2. 数据流的声明参数中,泛型参数一定要有默认值,通常是默认null。我的习惯是全部参数都给默认值,这样可以有一个无参的构造函数。

  3. 我们通过保存泛型类型的方式,来达到无法获取泛型的ClassLoader的问题。也就是这篇文章的最重要的点:

    constructor(source: Parcel) : this() {
     ...
        val className = source.readString()
        data = if(className == EMPTY) null else source.readParcelable(Class.forName(className).getClassLoader())
    }
    
    override fun writeToParcel(dest: Parcel, flags: Int) {
        ...
        dest.writeString(if(this.data==null) EMPTY else this.data!!::class.java.name)
        dest.writeParcelable(this.data, flags)
    } 
    

相关文章

  • Kotlin中泛型的序列化Parcelable

    系列文章全部为本人的学习笔记,若有任何不妥之处,随时欢迎拍砖指正。如果你觉得我的文章对你有用,欢迎关注我以及我的K...

  • Kotlin使用parcelable出现:BadParcelab

    在Kotlin编写代码过程中,需要用到parcelable来进行传值,按照以前的写法,进行序列化: 这样序列化的实...

  • Kotlin:泛型杂谈(下)

    在Kotlin:泛型杂谈(上)中,从泛型扩展属性、非空约束、实例化类型参数三个方面简单介绍了一下Kotlin中泛型...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • 为 Kotlin 中的 Boolean 类扩展一套流式 API

    近日拜读了大佬 mikyou 一篇讲 Kotlin 中泛型的 文章,里面说到 Kotlin 中泛型应用场景的问题时...

  • Kotlin 泛型

    Kotlin 中也有泛型的概念,和 Java 中的类似,但又不尽相同,一起来认识 Kotlin 中的泛型吧。 一、...

  • 泛型

    与Java泛型相同,Kotlin同样提供了泛型支持。对于简单的泛型类、泛型函数的定义,Kotlin 与 Java ...

  • Kotlin---泛型

    Kotlin不变型泛型 Kotlin的不变型泛型和Java一样,通过声明泛型类型来使用泛型类。而该种泛型声明后,则...

  • Kotlin 泛型

    Kotlin 泛型 1. 泛型类 定义一个泛型类 使用 在继承中 使用 2. 泛型函数 使用 3. 泛型的擦除 无...

  • Kotlin入门潜修之类和对象篇—泛型及其原理

    泛型 如果我们了解java中的泛型,那么本篇文章提到的kotlin泛型我们也不会陌生。但是如果之前没有接触过泛型或...

网友评论

    本文标题:Kotlin中泛型的序列化Parcelable

    本文链接:https://www.haomeiwen.com/subject/vtpdhxtx.html