[Android]序列化原理Parcelable

 Parcelable是Android为我们提供的序列化的接口,Parcelable相对于Serializable的使用相对复杂一些,但Parcelable的效率相对Serializable也高很多,这一直是Google工程师引以为傲的,Parcelable和Serializable的效率对比Parcelable vs Serializable号称快10倍的效率

Parcelable是Android SDK提供的,它是基于内存的,由于内存读写速度高于硬盘,由此Android中的跨进程对象的传递一般使用Parcelable

Parcelable实现生成器


kotlin-parcelize 插件提供了一个 Parcelable 实现生成器,将以下 Gradle 插件添加到应用的 build.gradle 文件中:

plugins {
    id("kotlin-parcelize")
}

当使用 @Parcelize 为类添加注解时,系统会自动生成一个 Parcelable的 实现,如以下所示:

import kotlinx.parcelize.Parcelize

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

要注意的是:@Parcelize 要求在主要构造函数中声明所有序列化属性。

 如果您的类需要更高级的序列化逻辑,请将其写在某个伴随类中:

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

Parcelable序列化过程的源码解析


 Parcelable接口

Parcelable接口里面有个writeToParcel方法

 到writeToParcel方法的Parcel类里面来,Parcel相对于快递员的包裹,需要我们把数据写到Parcel里面去,然后收件人可以从包裹从获取数据。

 Parcel里面有一系列的native方法,native方法是干什么的呢?native方法就是把我们的数据类型写进去。

总得来说: Parcelable通过Parcel实现读和写,从而实现序列化和反序列化

 Parcelable序列化基本方法


 private fun test() {
        var parcel:Parcel=Parcel.obtain()
        parcel.writeInt(19)
        parcel.writeInt(12)
        //marshall方法转换成二进制
        val bs=parcel.marshall()
        Log.d("data","bs=${bs.size}")
        //把parcel释放掉
        parcel.setDataPosition(0)
        parcel.recycle()
        //重新获取一个parcel
        parcel=Parcel.obtain()
        //把bs字节流放到parcel里面去
        parcel.unmarshall(bs,0,bs.size)
        //把parcel里面的值读取出来
        val size=parcel.dataSize()
        for(i in 0..size step 4){
            parcel.setDataPosition(i)
            Log.d("data","value=${parcel.readInt()}")
        }
        parcel.recycle()
    }

 Parcelable进程间传递对象


创建Course类实现Parcelable接口

@Parcelize
class Course(var name:String, var score:Int) :Parcelable{
}

 在一个activity中写下如下代码

       val course=Course("数学",99)
        var intent=Intent(this,MainActivity4::class.java)
        intent.putExtra("data",course)
        startActivity(intent)

在另一个activity中写下如下代码 

        var course=intent.getParcelableExtra<Course>("data")
        if (course != null) {
            Log.d("data","${course.name}---${course.score}")
        }

结果展示 

 D/data: 数学---99

Parcelable和Serializable如何选择


1.在使用内存方面,Parcelable比Serializable性能高,所以推荐使用Parcelable。

2.Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。

3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性,在外界有变化的情况下,建议使用Serializable。

猜你喜欢

转载自blog.csdn.net/weixin_63357306/article/details/128574077