Android中的Serialization、Parcelable

Parcelable

這是一個接口,它的實(shí)例可以寫入Parcel或從Parcel恢復(fù)。實(shí)現(xiàn)Parcelable的類必須要有一個實(shí)現(xiàn)了Parcelable.Creator接口的類型的非空靜態(tài)字段CREATOR,這個字段是幫忙從一個Parcel產(chǎn)生一個Parcelable類的實(shí)例。

public class MyParcelable implements Parcelable {
     private int mData;

     public int describeContents() {
         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();
     }
 }
  • describeContents()用于描述Parcelable類實(shí)例的
  • writeToParcel(Parcel dest, int flags)用于將數(shù)據(jù)扁平化寫入Parcel

Parcel是一個消息(數(shù)據(jù)或?qū)ο笠茫┤萜?,它可以通過IBinder來發(fā)送,也就是說 Parcelable實(shí)例十分合適作來進(jìn)程間通信的消息載體。

java中使用Serializable接口實(shí)現(xiàn)對象的序列化,而在android中既可以使用Serializable也可以使用Parcelable接口實(shí)現(xiàn)對象序列化,如果只在內(nèi)存操作時則傾向Parcelable接口,傳輸效率會更高效。

注意:Parcelable只能對內(nèi)存對象序列化,不能對需要存儲在文件或SD等設(shè)備進(jìn)行序列化,如果需要將對象序列化存儲到文件,實(shí)現(xiàn)Serializable接口就可以了

Serializablejava提供的一個序列化接口,它是一個空接口,專門為對象提供標(biāo)準(zhǔn)的序列化和反序列化操作,用它實(shí)現(xiàn)類的序列化比較簡單,只要在類聲明中實(shí)現(xiàn)Serializable接口即可。

public class User implements Serializable {
    private static final long serialVersionUID = -4454266436543306544L;

    private String name;
    /**
     * age
     */
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

由于serialVersionUID是用來輔助序列化和反序列化過程的,原則上序列化后的對象中serialVersionUID只有和當(dāng)前類的serialVersionUID相同才能夠正常被反序列化,也就是說序列化與反序列化的serialVersionUID必須相同才能夠使序列化操作成功。序列化操作的時候系統(tǒng)會把當(dāng)前類的serialVersionUID寫入到序列化文件中,當(dāng)反序列化時系統(tǒng)會去檢測文件中的serialVersionUID,判斷它是否與當(dāng)前類的serialVersionUID一致,如果一致就說明序列化類的版本與當(dāng)前類版本是一樣的,可以反序列化成功,否則失敗。因此強(qiáng)烈建議指定serialVersionUID,這樣的話即使微小的變化也不會導(dǎo)致crash的出現(xiàn),否則文件多一個空格或類的結(jié)構(gòu)有些許變化都會反序列化失敗。默認(rèn)情況下,系統(tǒng)會根據(jù)類結(jié)構(gòu)自動生成的serialVersionUID,因此當(dāng)類稍有變化,自動生成的UID就會與之前存在文件中的不一樣,就會反序列化失敗。因此有必要指定serialVersionUID,那么系統(tǒng)就會盡可能地序列化。

需要注意的是如果反序列的類的成員變量的類型或者類名發(fā)生了變化,即使serialVersionUID相同反序列化會失敗。其次是靜態(tài)成員變量屬于類不屬于對象,不會參與序列化過程,使用transient關(guān)鍵字標(biāo)記的成員變量也不參與序列化過程。

Serializable在內(nèi)存序列化是(將數(shù)據(jù)持久化在磁盤)上開銷比較大,如Serializable在序列化的時候會產(chǎn)生大量的臨時變量,從而引起頻繁的GC(垃圾回收),而內(nèi)存資源對于android系統(tǒng)來說是十分稀有的(首先,我們每個應(yīng)用都會運(yùn)行在各自的虛擬機(jī)上,而android系統(tǒng)分配給每個虛擬機(jī)的內(nèi)存開銷都是十分有限的)。因此android中提供了Parcelable接口來實(shí)現(xiàn)序列化操作,Parcelable的性能比Serializable好,在內(nèi)存開銷方面較小,所以在內(nèi)存間數(shù)據(jù)傳輸時推薦使用Parcelable,如通過Intent在activity間傳輸數(shù)據(jù),進(jìn)程間通信也推薦使用Parcelable

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

相關(guān)閱讀更多精彩內(nèi)容

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