第七周 關(guān)于序列化的知識(shí)

話題:關(guān)于序列化的知識(shí)

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將你的對(duì)象映射成Parcel對(duì)象,再通過createFromParcel將Parcel對(duì)象映射成你的對(duì)象。也可以將Parcel看成是一個(gè)流,通過writeToParcel把對(duì)象寫到流里面,在通過createFromParcel從流里讀取對(duì)象,只不過這個(gè)過程需要你來實(shí)現(xiàn),因此寫的順序和讀的順序必須一致。

(2) Serializable的使用:

Serializable的實(shí)現(xiàn),只需要implements Serializable 即可。這只是給對(duì)象打了一個(gè)標(biāo)記,系統(tǒng)會(huì)自動(dòng)將其序列化。

在序列化過程中會(huì)自動(dòng)生成一個(gè)serialVersionUID來標(biāo)識(shí)序列化對(duì)象。serialVersionUID是用來輔助序列化和反序列化過程的,序列化與反序列化的serialVersionUID必須相同才能夠使序列化操作成功。

具體過程是這樣的:序列化操作的時(shí)候系統(tǒng)會(huì)把當(dāng)前類的serialVersionUID寫入到序列化文件中,當(dāng)反序列化時(shí)系統(tǒng)會(huì)去檢測(cè)文件中的serialVersionUID,判斷它是否與當(dāng)前類的serialVersionUID一致,如果一致就說明序列化類的版本與當(dāng)前類版本是一樣的,可以反序列化成功,否則失敗。

報(bào)出如下UID錯(cuò)誤:

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

(3)區(qū)別:

  1. Serializable接口(是JavaSE本身就支持的),Parcelable接口(是Android特有功能,效率比實(shí)現(xiàn)Serializable接口高效,可用于Intent數(shù)據(jù)傳遞,也可以用于進(jìn)程間通信(IPC))。
  2. 在使用內(nèi)存的時(shí)候,Parcelable比Serializable性能高,所以推薦使用Parcelable

(4)選取原則:

  1. 在使用內(nèi)存的時(shí)候,Parcelable比Serializable性能高,所以推薦使用Parcelable。
  2. Serializable在序列化的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量,從而引起頻繁的GC。
  3. Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn), 也不提倡用,但在這種情況下,還是建議你用Serializable 。

2、自定義一個(gè)類讓其實(shí)現(xiàn)Parcelable,大致流程是什么?

見答案1。

3、枚舉如何實(shí)現(xiàn)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);
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容