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。