序列化

作者: 吃茶泡饭丶 | 来源:发表于2018-10-11 00:46 被阅读0次
序列化的目的

将对象数据转换成字节流形式

我们知道网络传输是以字节流的方式对数据进行传输的。而当我们通过Intent和Binder传输数据时,无论何种类型的数据,都以字节流形式传送。

对象的序列化主要用途:

  • 永久的保存对象(将对象保存在文件或者磁盘中)
  • 方便对象数据在网络与进程间进行传递
Android中实现序列化的方式
  • 实现Serializable接口
import java.io.Serializable;

使用方法只需要实现Serializable即可

import java.io.Serializable;

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/11
 * @Description:
 */
public class Person implements Serializable{
    private static final long serialVersionUID = 4890701529857339249L;
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

设置Android studio实现Serializable自动生成serialVersionUID步骤:

1、File–>Settings–>Editor–>Inspections–>Java–>Serialization issues–>Serializable class without ‘serialVersionUID’ 勾选中该选项即可。
2、进入实现了Serializable中的类,选中类名,Alt+Enter弹出提示,然后直接导入完成

serialVersionUID的作用:

s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D​:​ ​字​面​意​思​上​是​序​列​化​的​版​本​号,是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量;原则上序列化后的数据中的serialVersionUID只有和当前类的serialVersionUID相同才能够正常地被反序列化。(当s​e​r​i​a​l​V​e​r​s​i​o​n​U​I​D一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化;否则说明当前类和反序列化的类相比发生了某些变化,比如成员变量的数量、类型发生了变化,这个时候是无法正常反序列化的)

为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。当然也可以不那么做!

对于使用序列化的两点注意:

对于使用序列化还有两点需要注意:
1.静态成员变量属于类不属于对象,所以不参与序列化过程
2.用transient关键字标记的成员变量不参与序列化过程

上述两点注意同样适用Parcelable

  • 实现Parcelable接口
import android.os.Parcelable;

Parcelable相比Serializable具有更好的性能,但是使用更复杂,Parcelable不仅仅需要声明,还需要实现内部的相应方法,不过这些AS可以帮我们做好。

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/11
 * @Description:
 */
public class Person implements Parcelable{

    private String name;
    private int age;
    private List<String> child;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List<String> getChild() {
        return child;
    }

    public void setChild(List<String> child) {
        this.child = child;
    }

    protected Person(Parcel in) {
        name = in.readString();
        age = in.readInt();
        child = in.createStringArrayList();
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        /**
         * 从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层
         * 简单来说就是将Parcel对象映射成你的对象
         * @param in
         * @return
         */
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    /**
     * 内容接口描述,默认返回0就可以
     * @return
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 将对象序列化为一个Parcel对象
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeStringList(child);
    }
}

Kotlin实现方式:

/**
 * @Author: chichapaofan
 * @CreateDate: 2018/10/11
 * @Description:
 */
data class Person(val name:String,val age:Int,val child:List<String>):Parcelable {

    constructor(parcel: Parcel) : this(
            parcel.readString(),
            parcel.readInt(),
            parcel.createStringArrayList()) {
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(name)
        parcel.writeInt(age)
        parcel.writeStringList(child)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<Person1> {
        override fun createFromParcel(parcel: Parcel): Person1 {
            return Person1(parcel)
        }

        override fun newArray(size: Int): Array<Person1?> {
            return arrayOfNulls(size)
        }
    }
}

注意:写入数据的顺序和读出数据的顺序必须是相同的.

比较
  • Serializable在序列化操作的时候会产生大量的临时变量,(原因是使用了反射机制)从而导致GC的频繁调用,因此在性能上会稍微逊色

  • Parcelable是以Ibinder作为信息载体的.在内存上的开销比较小,因此在内存之间进行数据传递的时候,Android推荐使用Parcelable,既然是内存方面比价有优势,那么自然就要优先选择。

  • 在读写数据的时候,Parcelable是在内存中直接进行读写,而Serializable是通过使用IO流的形式将数据读写入在硬盘上。Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性。

相关文章

网友评论

      本文标题:序列化

      本文链接:https://www.haomeiwen.com/subject/xdpmaftx.html