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。