Android中的序列化:Parcelable和Serializable

概述

序列化:將一個(gè)對(duì)象轉(zhuǎn)換成可存儲(chǔ)可傳輸的狀態(tài)。

Parcelable和Serializable的區(qū)別

作用

Serializable的作用是為了保存對(duì)象的屬性到本地文件、數(shù)據(jù)庫(kù)、網(wǎng)絡(luò)流、rmi以方便數(shù)據(jù)傳輸,當(dāng)然這種傳輸可以是程序內(nèi)的也可以是兩個(gè)程序間的。

Parcelable的設(shè)計(jì)初衷是因?yàn)镾erializable效率過慢,為了在程序內(nèi)不同組件間以及不同Android程序間(AIDL)高效的傳輸數(shù)據(jù)而設(shè)計(jì),這些數(shù)據(jù)僅在內(nèi)存中存在,Parcelable是通過IBinder通信的消息的載體。

性能比較

  • 在內(nèi)存的使用中,Parcelable的性能方面要強(qiáng)于Serializable;
  • Serializable序列化操作的時(shí)候會(huì)產(chǎn)生大量的臨時(shí)變量(原因是使用了反射機(jī)制),從而導(dǎo)致GC的頻繁調(diào)用,因而性能比Parcelable差;
  • Parcelable是以IBinder作為信息載體的。在內(nèi)存上的開銷比較小,因此內(nèi)存直接進(jìn)行數(shù)據(jù)傳遞的時(shí)候,Android推薦使用Parcelable;
  • 在讀寫數(shù)據(jù)的時(shí)候,Parcelable是在內(nèi)存中直接進(jìn)行讀寫,而Serializable是通過IO流的形式將數(shù)據(jù)寫入到硬盤上。

選擇

Parcelable的性能比Serializable好,在內(nèi)存開銷方面較小,所以在內(nèi)存間數(shù)據(jù)傳輸時(shí)推薦使用Parcelable,如Activity間傳輸數(shù)據(jù),而Serializable可將數(shù)據(jù)持久化方便保存,所以在需要保存或網(wǎng)絡(luò)傳輸數(shù)據(jù)時(shí)選擇Serializable,因?yàn)锳ndroid不同版本Parcelable可能不同,所以不推薦使用Parcelable進(jìn)行數(shù)據(jù)持久化。

Serializable的使用

對(duì)于Serializable的使用,類只需要實(shí)現(xiàn)Serializable接口。

public class User implements Serializable {
    
    /**
     * Java的序列化機(jī)制是通過判斷類的serialVersionUID來驗(yàn)證版本一致性的。
     * 在進(jìn)行反序列化時(shí),JVM會(huì)把傳來的字節(jié)流中的serialVersionUID與本地相應(yīng)實(shí)體類的serialVersionUID進(jìn)行比較,
     * 如果相同就認(rèn)為是一致的,可以進(jìn)行反序列化,否則就會(huì)出現(xiàn)序列化版本不一致的異常,即是InvalidCastException。
     * (如果沒有顯示定義,Java序列化機(jī)制會(huì)根據(jù)編譯的Class自動(dòng)生成一個(gè)serialVersionUID做為序列化版本比較用,如果Class文件沒有發(fā)生變化,則serialVersionUID不變)
     */
    private static final long serialVersionUID = 123456789L;
    
    private String uid;
    private String userName;
    private int age;
}

Parcelable的使用

Parcelable的使用,需要實(shí)現(xiàn)writeToParcel、describeContents函數(shù)以及靜態(tài)的CREATOR變量。

public class User implements Parcelable {
    private String uid;
    private String userName;
    private int age;

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.uid);
        dest.writeString(this.userName);
        dest.writeInt(this.age);
    }

    public User() {
    }

    protected User(Parcel in) {
        this.uid = in.readString();
        this.userName = in.readString();
        this.age = in.readInt();
    }

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

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

參考鏈接

  1. Parcelable和Serializable的作用、效率、區(qū)別及選擇
  2. Android系統(tǒng)中Parcelable和Serializable的區(qū)別
  3. 序列化Serializable和Parcelable的理解和區(qū)別
  4. Android中Serializable和Parcelable序列化對(duì)象詳解
  5. Serializable
  6. Parcelable
  7. java類中serialversionuid 作用 是什么?
編碼前線.jpg
?著作權(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),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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