Android中Serializable和Parcelable接口

Android中實(shí)現(xiàn)序列化有兩個(gè)選擇:一個(gè)是實(shí)現(xiàn)Serializable接口贷洲,Java提供的一個(gè)序列化接口寇损;另一個(gè)是實(shí)現(xiàn)Parcelable接口,Android特有的序列化接口,效率比實(shí)現(xiàn)Serializable接口高效移袍,可用于Intent數(shù)據(jù)傳遞,也可以用于進(jìn)程間通信(IPC)老充。

序列化和反序列化

  • 序列化:用來(lái)處理對(duì)象流的機(jī)制葡盗,所謂對(duì)象流就是將對(duì)象的內(nèi)容進(jìn)行流化。方便對(duì)流化后的對(duì)象進(jìn)行讀寫操作啡浊,也可在網(wǎng)絡(luò)間傳輸觅够。簡(jiǎn)單來(lái)說(shuō)是一種將對(duì)象以一連串的字節(jié)描述的過(guò)程。

  • 反序列化:將流化后的對(duì)象重新構(gòu)成對(duì)象的過(guò)程巷嚣。

序列化應(yīng)用場(chǎng)景

  • 永久性保存對(duì)象喘先,保存對(duì)象的字節(jié)序列到本地文件中
  • 通過(guò)序列化對(duì)象在網(wǎng)絡(luò)中傳輸
  • 通過(guò)序列化在進(jìn)程間傳遞對(duì)象

Serializable序列化ID:

序列化ID serialVersionUID的值可以是固定的1L,也可以是隨機(jī)生成一個(gè)不重復(fù)的long類型數(shù)據(jù)廷粒,甚至可以不聲明也可以實(shí)現(xiàn)序列化窘拯。但是會(huì)對(duì)反序列化過(guò)程產(chǎn)生影響,因?yàn)椴煌男蛄谢疘D之間不能進(jìn)行序列化和反序列化坝茎。

Serializable實(shí)現(xiàn)序列化步驟

  • 創(chuàng)建某些OutputStream對(duì)象:OutputStream outputStream = new FileOutputStream("output.txt");

  • 將其封裝到ObjectOutputStream對(duì)象內(nèi):ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

  • 調(diào)用writeObject()即可完成對(duì)象的序列化涤姊,并將其發(fā)送給OutputStream:objectOutputStream.writeObject(Object);

  • 關(guān)閉資源:objectOutputStream.close()和outputStream.close();

Serializable實(shí)現(xiàn)反序列化步驟

  • 創(chuàng)建某些InputStream對(duì)象:InputStream inputStream = new FileInputStream("output.txt");

  • 將其封裝到ObjectInputStream對(duì)象內(nèi):ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);

  • 調(diào)用readObject()即可完成對(duì)象的反序列化:object = objectInputStream.readObject();

  • 關(guān)閉資源:objectInputStream.close()和inputStream.close();

注意:

  • 靜態(tài)變量屬于類不屬于對(duì)象,所以不會(huì)參與序列化過(guò)程嗤放。
  • 用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過(guò)程思喊。(通過(guò)用這個(gè)關(guān)鍵字可以控制想要序列化的成員變量

Serializable代碼實(shí)例:

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name= name;
        this.age= 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;
    }
}

// Serializable:把對(duì)象序列化
public static void writeSerializableObject() {
    try {
        Person person = new Person("Mary", 18);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("output.txt"));
        objectOutputStream.writeObject(person);
        objectOutputStream.close();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

// Serializable:反序列化對(duì)象
public static void readSerializableObject() {
    try {
        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("output.txt"));
        Person person = (Person) objectInputStream.readObject();
        objectInputStream.close();
        System.out.println("name = " + person.getName() + ", age = " + person.getAge());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Parcelable接口定義

public interface Parcelable 
{
    //內(nèi)容描述接口,基本不用管
    public int describeContents();
    //寫入接口函數(shù)次酌,打包
    public void writeToParcel(Parcel dest, int flags);
    //讀取接口恨课,目的是要從Parcel中構(gòu)造一個(gè)實(shí)現(xiàn)了Parcelable的類的實(shí)例處理。因?yàn)閷?shí)現(xiàn)類在這里還是不可知的岳服,所以需要用到模板的方式剂公,繼承類名通過(guò)模板參數(shù)傳入
    //為了能夠?qū)崿F(xiàn)模板參數(shù)的傳入,這里定義Creator嵌入接口,內(nèi)含兩個(gè)接口函數(shù)分別返回單個(gè)和多個(gè)繼承類實(shí)例
    public interface Creator<T> 
    {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
    }
}

Parcelable實(shí)現(xiàn)序列化步驟

  • 實(shí)現(xiàn)Parcelable接口

  • 重寫writeToParcel方法吊宋,將你的對(duì)象序列化為一個(gè)Parcel對(duì)象诬留,即:將類的數(shù)據(jù)寫入外部提供的Parcel中,打包需要傳遞的數(shù)據(jù)到Parcel容器保存,以便從 Parcel容器獲取數(shù)據(jù)

  • 重寫describeContents方法文兑,內(nèi)容接口描述盒刚,默認(rèn)返回0就可以

  • 實(shí)例化靜態(tài)內(nèi)部對(duì)象CREATOR實(shí)現(xiàn)接口Parcelable.Creator。需重寫本接口中的兩個(gè)方法:createFromParcel(Parcel in) 實(shí)現(xiàn)從Parcel容器中讀取傳遞數(shù)據(jù)值绿贞,封裝成Parcelable對(duì)象返回邏輯層因块,newArray(int size) 創(chuàng)建一個(gè)類型為T,長(zhǎng)度為size的數(shù)組籍铁,僅一句話即可(return new T[size])涡上,供外部類反序列化本類數(shù)組使用。

public static final Parcelable.Creator<T> CREATOR

Parcelable代碼實(shí)例:

public class Person implements Parcelable 
{
     private String name;
     private String sex;
     private int age;

     public int describeContents() 
     {
         return 0;
     }

     public void writeToParcel(Parcel out, int flags) 
     {
         out.writeString(name);
         out.writeString(sex);
         out.writeInt(age);
     }

     public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() 
     {
         public Person createFromParcel(Parcel in) 
         {
             return new Person(in);
         }

         public Person[] newArray(int size) 
         {
             return new Person[size];
         }
     };
     
     private Person(Parcel in) 
     {
        name = in.readString();
        sex = in.readString();
         age = in.readInt();
     }
 }

Serializable和Parcelable對(duì)比

  • Serializable實(shí)現(xiàn)較簡(jiǎn)單拒名,只需要implements Serializable即可吩愧,系統(tǒng)會(huì)自動(dòng)將其序列化;而Parcelable的實(shí)現(xiàn)增显,不僅需要implements Parcelable雁佳,還需要在類中添加一個(gè)靜態(tài)成員變量CREATOR,這個(gè)變量需要實(shí)現(xiàn) Parcelable.Creator接口同云。

  • 使用內(nèi)存時(shí)糖权,Parcelable比Serializable性能高,推薦使用Parcelable炸站。

  • Parcelable不能使用在要將數(shù)據(jù)存儲(chǔ)在磁盤上的情況星澳,因?yàn)镻arcelable不能很好的保證數(shù)據(jù)的持續(xù)性在外界有變化的情況下。盡管Serializable效率低點(diǎn)旱易,但此時(shí)還是建議使用Serializable 禁偎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市阀坏,隨后出現(xiàn)的幾起案子如暖,更是在濱河造成了極大的恐慌,老刑警劉巖全释,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件装处,死亡現(xiàn)場(chǎng)離奇詭異误债,居然都是意外死亡浸船,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門寝蹈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)李命,“玉大人,你說(shuō)我怎么就攤上這事箫老》庾郑” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)阔籽。 經(jīng)常有香客問(wèn)我流妻,道長(zhǎng),這世上最難降的妖魔是什么笆制? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任绅这,我火速辦了婚禮,結(jié)果婚禮上在辆,老公的妹妹穿的比我還像新娘证薇。我一直安慰自己,他們只是感情好匆篓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布浑度。 她就那樣靜靜地躺著,像睡著了一般鸦概。 火紅的嫁衣襯著肌膚如雪箩张。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天完残,我揣著相機(jī)與錄音伏钠,去河邊找鬼。 笑死谨设,一個(gè)胖子當(dāng)著我的面吹牛熟掂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扎拣,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼赴肚,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了二蓝?” 一聲冷哼從身側(cè)響起誉券,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刊愚,沒想到半個(gè)月后踊跟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸥诽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年商玫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片牡借。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡拳昌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钠龙,到底是詐尸還是另有隱情炬藤,我是刑警寧澤御铃,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站沈矿,受9級(jí)特大地震影響上真,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜羹膳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一谷羞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧溜徙,春花似錦湃缎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至图贸,卻和暖如春蹂季,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疏日。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工偿洁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沟优。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓涕滋,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親挠阁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宾肺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容