第七周 关于序列化的知识

话题:关于序列化的知识

1、Parcelable和Serializable有什么用,它们有什么差别?

(1) Parcelable的使用:

 * public class MyParcelable implements Parcelable {
 *     private int mData;
 *
 *    /*
 *    * Bit masks for use with {@link #describeContents}: each bit represents a
 *    * kind of object considered to have potential special significance when
 *    * marshalled.
 *    */
 *     public int describeContents() {
 *        //一共返回2种返回值 0 与 CONTENTS_FILE_DESCRIPTOR
 *       //一般返回0,特殊情况下返回CONTENTS_FILE_DESCRIPTOR
 *         return 0;
 *     }
 *
 *     public void writeToParcel(Parcel out, int flags) {
 *         out.writeInt(mData);
 *     }
 *
 *     public static final Parcelable.Creator<MyParcelable>  CREATOR
 *             = new Parcelable.Creator<MyParcelable>() {
 *         public MyParcelable createFromParcel(Parcel in) {
 *             return new MyParcelable(in);
 *         }
 *
 *         public MyParcelable[] newArray(int size) {
 *             return new MyParcelable[size];
 *         }
 *     };
 *     
 *     private MyParcelable(Parcel in) {
 *         mData = in.readInt();
 *     }
 * }

通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,在通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,因此写的顺序和读的顺序必须一致。

(2) Serializable的使用:

Serializable的实现,只需要implements Serializable 即可。这只是给对象打了一个标记,系统会自动将其序列化。

在序列化过程中会自动生成一个serialVersionUID来标识序列化对象。serialVersionUID是用来辅助序列化和反序列化过程的,序列化与反序列化的serialVersionUID必须相同才能够使序列化操作成功。

具体过程是这样的:序列化操作的时候系统会把当前类的serialVersionUID写入到序列化文件中,当反序列化时系统会去检测文件中的serialVersionUID,判断它是否与当前类的serialVersionUID一致,如果一致就说明序列化类的版本与当前类版本是一样的,可以反序列化成功,否则失败。

报出如下UID错误:

Exception in thread "main" java.io.InvalidClassException: com.android.test.Client; 
local class incompatible: stream classdesc serialVersionUID = 
-2656541345465468483
local class serialVersionUID = -1546464648434364595
                                                 

(3)区别:

  1. Serializable接口(是JavaSE本身就支持的),Parcelable接口(是Android特有功能,效率比实现Serializable接口高效,可用于Intent数据传递,也可以用于进程间通信(IPC))。
  2. 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable

(4)选取原则:

  1. 在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
  2. Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
  3. Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点, 也不提倡用,但在这种情况下,还是建议你用Serializable 。

2、自定义一个类让其实现Parcelable,大致流程是什么?

见答案1。

3、枚举如何实现Parcelable 接口

public enum Option implements Parcelable {

    DATA_BASE("Database"), TRIPS("Trips");

    private String option;

    Option(String option){
        this.option = option;
    }

    public String getName(){
        return option;
    }

    private void setOption(String option){
        this.option = option;
    }

    public static final Parcelable.Creator<Option> CREATOR = new Parcelable.Creator<Option>() {

        public Option createFromParcel(Parcel in) {
            Option option = Option.values()[in.readInt()];
            option.setOption(in.readString());
            return option;
        }

        public Option[] newArray(int size) {
            return new Option[size];
        }

    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(ordinal());
        out.writeString(option);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。