Kotlin注解实现Parcelable序列化流程详解
作者:cdAndroid
一. 概念介绍
1. 序列化
由于存在于内存中的对象都是暂时的,无法长期驻存,为了把对象的状态保持下来,这时需要把对象写入到磁盘或者其他介质中,这个过程就叫做序列化。
2. 反序列化
反序列化恰恰是序列化的反向操作,也就是说,把已存在在磁盘或者其他介质中的对象,反序列化(读取)到内存中,以便后续操作,而这个过程就叫做反序列化。
3. 实现序列化的条件
在Java中,一个对象要实现序列化操作,该类就必须实现了Serializable接口或者Parcelable接口,而Parcelable接口则是Android中特有的序列化接口。只要清楚知道实现序列化操作时必须实现Serializable接口或者Parcelable接口之一即可。
二. 序列化目的
(1)永久的保存对象数据(将对象数据保存在文件当中,或者是磁盘中)
(2)通过序列化操作将对象数据在网络上进行传输(由于网络传输是以字节流的方式对数据进行传输的。因此序列化的目的是将对象数据转换成字节流的形式)
(3)将对象数据在进程之间进行传递(Activity之间传递对象数据时,需要在当前的Activity中对对象数据进行序列化操作。在另一个Activity中需要进行反序列化操作讲数据取出)
(4)Java允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长(即每个对象都在JVM中)但在现实应用中,就可能要停止JVM运行,但有要保存某些指定的对象,并在将来重新读取被保存的对象。这是Java对象序列化就能够实现该功能。(可选择入数据库、或文件的形式保存)
(5)序列化对象的时候只是针对变量进行序列化,不针对方法进行序列化。(6)在Intent之间,基本的数据类型直接进行相关传递即可,但是一旦数据类型比较复杂的时候,就需要进行序列化操作了。
三. 如何选择
Serializable是通过I/O读写存储在磁盘上的,使用反射机制,序列化过程较慢,且在序列化过程中创建许多临时对象,容易触发GC。Parcelable是直接在内存中读写的,将一个完整的对象分解成Intent所支持的数据类型,不需要使用反射,所以Parcelable具有效率高,内存开销小的优点。
在Android日常开发中,为了方便实现序列化只需在实体类中实现Serializable接口即可,而实现Parcelable接口,则需要重写几个方法,较于复杂了些,如:
data class UserInfoBean( @SerializedName("address") val address: String?, @SerializedName("city") val city: String?, @SerializedName("createTime") val createTime: Int, @SerializedName("district") val district: String?, @SerializedName("id") val id: Int, @SerializedName("loginName") val loginName: String?, @SerializedName("mail") val mail: String?, @SerializedName("merchantId") val merchantId: Int, @SerializedName("phone") val phone: String?, @SerializedName("province") val province: String?, @SerializedName("remark") val remark: String?, @SerializedName("status") val status: Int, @SerializedName("updateTime") val updateTime: Int, @SerializedName("userName") val userName: String? ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readString(), parcel.readString(), parcel.readInt(), parcel.readString(), parcel.readInt(), parcel.readString(), parcel.readString(), parcel.readInt(), parcel.readString(), parcel.readString(), parcel.readString(), parcel.readInt(), parcel.readInt(), parcel.readString() ) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(address) parcel.writeString(city) parcel.writeInt(createTime) parcel.writeString(district) parcel.writeInt(id) parcel.writeString(loginName) parcel.writeString(mail) parcel.writeInt(merchantId) parcel.writeString(phone) parcel.writeString(province) parcel.writeString(remark) parcel.writeInt(status) parcel.writeInt(updateTime) parcel.writeString(userName) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<UserInfoBean> { override fun createFromParcel(parcel: Parcel): UserInfoBean { return UserInfoBean(parcel) } override fun newArray(size: Int): Array<UserInfoBean?> { return arrayOfNulls(size) } } }
在Kotlin,实现Parcelable接口来序列化的复杂性已经不复存在了,进入主题,请看下文~
四. 进入主题
升级Kotlin Gradle plugins和Android Studio plugin的版本在1.3.60以上,实现方式:
在模块级的build.gradle
中添加
apply plugin: 'kotlin-android-extensions'
android{
androidExtensions {
experimental = true
}
}
在对象类中添加@Parcelize
并实现Parcelable接口即可实现序列化(在低版本中可能存在警告忽略即可)。
由于在 Kotlin 1.4.20 中做了一个重要的更新,影响如下:
废弃了 kotlin-android-extensions 编译插件Parcelable 相关的功能,移到了新的插件 kotlin-parcelize
Kotlin Gradle plugins 升级到1.4.20以后,作以下修改:
// apply plugin: 'kotlin-android-extensions'
// 改为
apply plugin: 'kotlin-parcelize'
在实体类导包中将 import kotlinx.android.parcel.Parcelize
修改为import kotlinx.parcelize.Parcelize
,但是这一步不是必须的,kotlinx.android.parcel.Parcelize
可以继续使用,到目前为止还没有发现什么问题(PS: 如果出现问题,只需要将包名替换就好)
到此这篇关于Kotlin注解实现Parcelable序列化流程详解的文章就介绍到这了,更多相关Kotlin Parcelable内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!