Android对象序列化
主要有两种方式:Serializable
和Parcelable
。
Serializable实际是使用Java的反射机制对对象做序列化和反序列化,其性能远低于使用Parcelable。
但是使用Java写的Parcelable有点繁琐,需要我们实现Parcelable接口,手写很多模板代码。
Java版的Parclable,需要重写wirteToParcel方法序列化对象,需要创建以Parcle为参数的构造函数用来对对象反序列化。需要构建Parclable.Creator。
json字符串:
{
"msg": "",
"code": "succeed",
"login_status": 0,
"mall_uid": "epet_0",
"mall_user": "",
"sys_time": 1494388655,
"push_alias": "",
"push_tags": "version3",
"categorys": [
{
"cateid": 53,
"name": "狗狗玩具",
"children": [
{
"type": "cateid",
"id": "210",
"name": "棉制玩具",
"photo": "http://i.epetbar.com/nowater/cates/2014-03/24/fcab37ead00d77bcdddf7dabe6c817d7.jpg"
},
{
"type": "cateid",
"id": "211",
"name": "橡胶玩具",
"photo": "http://i.epetbar.com/nowater/2016-07/21/14/874299e54a8cf1488d6b1bead8f8e9bb.jpg"
},
{
"type": "cateid",
"id": "212",
"name": "塑料玩具",
"photo": "http://i.epetbar.com/nowater/cates/2014-03/24/df1ed7120376370a4b5badaae61a0a7e.jpg"
},
{
"type": "cateid",
"id": "213",
"name": "手工玩具",
"photo": "http://i.epetbar.com/nowater/cates/2014-03/24/6709410560b999ab37ffb9747bb2ee71.jpg"
},
{
"type": "cateid",
"id": "3088",
"name": "食用玩具",
"photo": "http://i.epetbar.com/nowater/cates/2014-03/24/a5c7619872749790f6d6fd1ff3eccedc.jpg"
},
{
"type": "cateid",
"id": "4157",
"name": "木质玩具",
"photo": "http://i.epetbar.com/nowater/cates/2014-03/24/e9145de044fd5cec4c9b8ed47360d98f.jpg"
},
{
"type": "cateid",
"id": "4188",
"name": "梵米派",
"photo": "http://i.epetbar.com/nowater/cates/2015-07/28/45c339f6acb56364132b92f04b090c5c.jpg"
}
]
}
],
"topadv": {
"advid": "20605",
"src": "https://img2.epetbar.com/nowater/2017-04/05/14/19427a29344bcc0f385ca4718adca02f.jpg",
"title": "红脚丫",
"param": {
"mode": "web",
"param": "http://sale.epet.com/m/mould/activity/ztMTAzOA%3D%3D.html?tid=1038"
}
},
"owner": 53
}
使用插件(json to kotlin class)自动生成bean类
使用类似GsonFormat, 但这个可以生成内部类也可以选择不生成。
一、Serializable 序列化
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable {
因为ArrayList已实现Serializable,所以推荐将List换为ArrayList 。
内部类Serializable 序列化:实现Serializable即可
data class TestBean(
val categorys: ArrayList<Category>,
val code: String,
val login_status: Int,
val mall_uid: String,
val mall_user: String,
val msg: String,
val owner: Int,
val push_alias: String,
val push_tags: String,
val sys_time: Int,
val topadv: Topadv
) : Serializable {
data class Category(
val cateid: Int,
val children: ArrayList<Children>,
val name: String
) : Serializable {
data class Children(
val id: String,
val name: String,
val photo: String,
val type: String
) : Serializable
}
data class Topadv(
val `param`: Param,
val advid: String,
val src: String,
val title: String
) : Serializable {
data class Param(
val `param`: String,
val mode: String
)
}
}
非内部类Serializable 序列化:
data class TestBean(
val categorys: ArrayList<Category>,
val code: String,
val login_status: Int,
val mall_uid: String,
val mall_user: String,
val msg: String,
val owner: Int,
val push_alias: String,
val push_tags: String,
val sys_time: Int,
val topadv: Topadv
) : Serializable
data class Category(
val cateid: Int,
val children: ArrayList<Children>,
val name: String
) : Serializable
data class Children(
val id: String,
val name: String,
val photo: String,
val type: String
) : Serializable
data class Topadv(
val `param`: Param,
val advid: String,
val src: String,
val title: String
) : Serializable
data class Param(
val `param`: String,
val mode: String
) : Serializable
二、Parcelable序列化:插件Parcelable code generator
从上可看出非内部类结构更清晰,推荐非内部类
Parcelable序列化所需插件:
先将List 换成 ArrayList 或者 MutableList ,因为List不可修改,而ArrayList 或者 MutableList可修改。
类的后面右键(generator > Parcelable code generator)自动生成序列化 :
data class TestBean(
val categorys: ArrayList<Category>,
val code: String,
val login_status: Int,
val mall_uid: String,
val mall_user: String,
val msg: String,
val owner: Int,
val push_alias: String,
val push_tags: String,
val sys_time: Int,
val topadv: Topadv
) : Parcelable {
constructor(source: Parcel) : this(
source.createTypedArrayList(Category.CREATOR),
source.readString(),
source.readInt(),
source.readString(),
source.readString(),
source.readString(),
source.readInt(),
source.readString(),
source.readString(),
source.readInt(),
source.readParcelable<Topadv>(Topadv::class.java.classLoader)
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeTypedList(categorys)
writeString(code)
writeInt(login_status)
writeString(mall_uid)
writeString(mall_user)
writeString(msg)
writeInt(owner)
writeString(push_alias)
writeString(push_tags)
writeInt(sys_time)
writeParcelable(topadv, 0)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<TestBean> = object : Parcelable.Creator<TestBean> {
override fun createFromParcel(source: Parcel): TestBean = TestBean(source)
override fun newArray(size: Int): Array<TestBean?> = arrayOfNulls(size)
}
}
}
data class Category(
val cateid: Int,
val children: ArrayList<Children>,
val name: String
) : Parcelable {
constructor(source: Parcel) : this(
source.readInt(),
ArrayList<Children>().apply { source.readList(this, Children::class.java.classLoader) },
source.readString()
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeInt(cateid)
writeList(children)
writeString(name)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<Category> = object : Parcelable.Creator<Category> {
override fun createFromParcel(source: Parcel): Category = Category(source)
override fun newArray(size: Int): Array<Category?> = arrayOfNulls(size)
}
}
}
data class Children(
val id: String,
val name: String,
val photo: String,
val type: String
) : Parcelable {
constructor(source: Parcel) : this(
source.readString(),
source.readString(),
source.readString(),
source.readString()
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeString(id)
writeString(name)
writeString(photo)
writeString(type)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<Children> = object : Parcelable.Creator<Children> {
override fun createFromParcel(source: Parcel): Children = Children(source)
override fun newArray(size: Int): Array<Children?> = arrayOfNulls(size)
}
}
}
data class Topadv(
val `param`: Param,
val advid: String,
val src: String,
val title: String
) : Parcelable {
constructor(source: Parcel) : this(
source.readParcelable<Param>(Param::class.java.classLoader),
source.readString(),
source.readString(),
source.readString()
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeParcelable(param, 0)
writeString(advid)
writeString(src)
writeString(title)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<Topadv> = object : Parcelable.Creator<Topadv> {
override fun createFromParcel(source: Parcel): Topadv = Topadv(source)
override fun newArray(size: Int): Array<Topadv?> = arrayOfNulls(size)
}
}
}
data class Param(
val `param`: String,
val mode: String
) : Parcelable {
constructor(source: Parcel) : this(
source.readString(),
source.readString()
)
override fun describeContents() = 0
override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) {
writeString(param)
writeString(mode)
}
companion object {
@JvmField
val CREATOR: Parcelable.Creator<Param> = object : Parcelable.Creator<Param> {
override fun createFromParcel(source: Parcel): Param = Param(source)
override fun newArray(size: Int): Array<Param?> = arrayOfNulls(size)
}
}
}
三、Parcelable序列化:注解@Parcelize(推荐)
1、kotlin:>=1.1.4
在1.14的 Kotlin 插件中,已经自动包含了一个自动 Parcelable 实现生成器。简单来说,只需要再主函数中,声明序列化的属性并添加一个 @Parcelize 注解,它将自动为我们创建 writeToParcel() 和 createFromParcel()。也就是对开发者而言,只需要加一个 @Parcelize 注解,其它的和正常的类没有区别。
2、app的build.gradle添加插件
apply plugin: 'kotlin-android'//必须
apply plugin: 'kotlin-android-extensions' //必须
apply plugin: 'kotlin-kapt'
3、app的build.gradle下android配置添加
androidExtensions {
experimental = true
}
4、实体类上添加@Parcelize注解,实现 Parcelable
@Parcelize
data class TestBean(
val categorys: ArrayList<Category>,
val code: String,
val login_status: Int,
val mall_uid: String,
val mall_user: String,
val msg: String,
val owner: Int,
val push_alias: String,
val push_tags: String,
val sys_time: Int,
val topadv: Topadv
) : Parcelable
@Parcelize
data class Category(
val cateid: Int,
val children: ArrayList<Children>,
val name: String
) : Parcelable
@Parcelize
data class Children(
val id: String,
val name: String,
val photo: String,
val type: String
) : Parcelable
@Parcelize
data class Topadv(
val `param`: Param,
val advid: String,
val src: String,
val title: String
) : Parcelable
@Parcelize
data class Param(
val `param`: String,
val mode: String
) : Parcelable