1. 程式人生 > >Android序列化與反序列化

Android序列化與反序列化

1. 什麼是java序列化,如何實現java序列化?

我們有時候將一個java物件變成位元組流的形式傳出去或者從一個位元組流中恢復成一個java物件,例如,要將java物件儲存到硬碟或者傳送給網路上的其他計算機,這個過程我們可以自己寫程式碼去把一個java物件變成某個格式的位元組流再傳輸,但是,JRE本身就提供了這種支援,我們可以呼叫OutputStream的writeObject()方法來做,如果要讓java 幫我們做,要被傳輸的物件必須實現Serializable介面,這樣,javac編譯時就會進行特殊處理,編譯的類才可以被writeObject()方法操作,這就是所謂的序列化。需要被序列化的類必須實現Serializable介面,該介面是一個mini介面,其中沒有需要實現的方法,implements Serializable只是為了標註該物件是可被序列化的

例如,在web開發中,如果物件被儲存在了Session中,tomcat在重啟時要把Session物件序列化到硬碟,這個物件就必須實現Serializable介面。如果物件要經過分散式系統進行網路傳輸或通過rmi等遠端呼叫,這就需要在網路上傳輸物件,被傳輸的物件就必須實現Serializable介面

2. Serializable

Serializable是一個javase標記介面,會產生一個序列化值,該值跟bean的成員相關,所以實現Serilizable介面的時候,必須給一個uid,否則,當成員變化的時候,標記值也會變化,再次讀取的時候也出現exception(要先重新write再read,但是write可能會讓之前的資料丟失)

注意事項

  • 使用transient關鍵字宣告不需要序列化的成員變數
  • 序列化資料後,再次修改類檔案,讀取資料會出問題,如何解決呢?
private static final long serialVersionUID = -2071565876962058344L;

3. Parcelable

因為Serializable介面在序列化的時候會產生大量的臨時變數,效率較低,而Parcelable是android推出的高效序列化介面

Parcelable的方法說明

public final class Rect implements Parcelable {
    public int left;
    public
int top; public int right; public int bottom; public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() { public Rect createFromParcel(Parcel in) { return new Rect(in); } public Rect[] newArray(int size) { return new Rect[size]; } }; public Rect() { } private Rect(Parcel in) { readFromParcel(in); } public void writeToParcel(Parcel out) { out.writeInt(left); out.writeInt(top); out.writeInt(right); out.writeInt(bottom); } public void readFromParcel(Parcel in) { left = in.readInt(); top = in.readInt(); right = in.readInt(); bottom = in.readInt(); } }

Android Parcelable code generator

生成Parcelable程式碼

Parcelable程式碼生成外掛

4. Serialiable與Parcelable的區別

  • 在使用記憶體的時候,Parcelable 類比Serializable 效能高,首選使用Parcelable 類
  • Serializable 在序列化的時候會產生大量的臨時變數,從而引起頻繁的GC
  • 資料持久化,Parcelable 不能使用在要將資料儲存在磁碟上的情況。儘管Serializable 效率低點,但在這種情況下,還是建議你用Serializable

Serializable是Java中的序列化介面,其使用起來簡單但是開銷很大,序列化和反序列化過程需要大量I/O操作。而Parcelable是Android中的序列化方式,因此,更適合用在Android平臺上,它的缺點就是用起來稍微麻煩點,但是它的效率很高,這是Android推薦的序列化方式,因此,我們要首選Parcelable。Parcelable主要用在記憶體序列化上,通過Parcelable將物件序列化到儲存裝置中或者將物件序列化後通過網路傳輸也都是可以的,但是這個過程會稍顯複雜,因此在這兩種情況下建議大家使用Parcelable。

5. 序列化流ObjectOutputStream

ObjectOutputStream 將 Java 物件的基本資料型別和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)物件。通過在流中使用檔案可以實現物件的持久儲存。如果流是網路套接字流,則可以在另一臺主機上或另一個程序中重構物件。

只能將支援 java.io.Serializable 介面的物件寫入流中。每個 Serializable 物件的類都被編碼,編碼內容包括類名和類簽名、物件的欄位值和陣列值,以及從初始物件中引用的其他所有物件的閉包。

writeObject() 方法用於將物件寫入流中。所有物件(包括 String 和陣列)都可以通過 writeObject ()寫入。可將多個物件或基元寫入流中。必須使用與寫入物件時相同的型別和順序從相應 ObjectInputstream 中讀回物件。

還可以使用 DataOutput 中的適當方法將基本資料型別寫入流中。還可以使用 writeUTF() 方法寫入字串。

物件的預設序列化機制寫入的內容是:物件的類,類簽名,以及非瞬態和非靜態欄位的值。其他物件的引用(瞬態和靜態欄位除外)也會導致寫入那些物件。可使用引用共享機制對單個物件的多個引用進行編碼,這樣即可將物件的圖形恢復為最初寫入它們時的形狀。

構造方法

  • ObjectOutputStream()
    為完全重新實現 ObjectOutputStream 的子類提供一種方法,讓它不必分配僅由 ObjectOutputStream 的實現使用的私有資料。

  • ObjectOutputStream(OutputStream out) :
    建立寫入指定 OutputStream 的 ObjectOutputStream

6. 反序列化流ObjectInputStream

1、ObjectInputStream 對以前使用 ObjectOutputStream 寫入的基本資料和物件進行反序列化。

2、ObjectOutputStream 和 ObjectInputStream 分別與 FileOutputStream 和 FileInputStream 一起使用時,可以為應用程式提供對物件圖形的持久儲存。ObjectInputStream 用於恢復那些以前序列化的物件。其他用途包括使用套接字流在主機之間傳遞物件,或者用於編組和解組遠端通訊系統中的實參和形參。

3、ObjectInputStream 確保從流建立的圖形中所有物件的型別與 Java 虛擬機器中顯示的類相匹配。使用標準機制按需載入類。

4、只有支援 java.io.Serializable 或 java.io.Externalizable 介面的物件才能從流讀取。

5、readObject 方法用於從流讀取物件。應該使用 Java 的安全強制轉換來獲取所需的型別。在 Java 中,字串和陣列都是物件,所以在序列化期間將其視為物件。讀取時,需要將其強制轉換為期望的型別。

6、可以使用 DataInput 上的適當方法從流讀取基本資料型別。

7、預設情況下,物件的反序列化機制會將每個欄位的內容恢復為寫入時它所具有的值和型別。反序列化程序將忽略宣告為瞬態或靜態的欄位。對其他物件的引用使得根據需要從流中讀取這些物件。使用引用共享機制能夠正確地恢復物件的圖形。反序列化時始終分配新物件,這樣可以避免現有物件被重寫。

8、序列化操作問題:NotSerializableException:未序列化異常

9、為什麼要實現序列化?如何實現序列化?

類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。

該介面居然沒有任何方法,類似於這種沒有方法的介面被稱為標記介面。

10、序列化資料後,再次修改類檔案,讀取資料會出問題,如何解決呢?

每次修改java檔案的內容的時候,class檔案的id值都會發生改變。而讀取檔案的時候,會和class檔案中的id值進行匹配。所以,就會出問題。讓這個id值在java檔案中是一個固定的值,這樣,你修改檔案的時候,這個id值就不會發生改變。

我們要知道的是:看到類實現了序列化介面的時候,要想解決黃色警告線問題,就可以自動產生一個序列化id值。而且產生這個值以後,我們對類進行任何改動,它讀取以前的資料是沒有問題的。

11、我一個類中可能有很多的成員變數,有些我不想進行序列化。請問該怎麼辦呢?

使用transient關鍵字宣告不需要序列化的成員變數
程式碼示例:

package cn.itcast_07;  

import java.io.FileInputStream;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.ObjectInputStream;  
import java.io.ObjectOutputStream;  

/* 
 * 序列化流:把物件按照流一樣的方式存入文字檔案或者在網路中傳輸。物件 -- 流資料(ObjectOutputStream) 
 * 反序列化流:把文字檔案中的流物件資料或者網路中的流物件資料還原成物件。流資料 -- 物件(ObjectInputStream) 
 */  
public class ObjectStreamDemo {  
    public static void main(String[] args) throws IOException,  
            ClassNotFoundException {  
        // 由於我們要對物件進行序列化,所以我們先自定義一個類  
        // 序列化資料其實就是把物件寫到文字檔案  
        // write();  

        read();  
    }  

    private static void read() throws IOException, ClassNotFoundException {  
        // 建立反序列化物件  
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(  
                "oos.txt"));  

        // 還原物件  
        Object obj = ois.readObject();  

        // 釋放資源  
        ois.close();  

        // 輸出物件  
        System.out.println(obj);  
    }  

    private static void write() throws IOException {  
        // 建立序列化流物件  
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(  
                "oos.txt"));  

        // 建立物件  
        Person p = new Person("林青霞", 27);  

        // public final void writeObject(Object obj)  
        oos.writeObject(p);  

        // 釋放資源  
        oos.close();  
    }  
}  

7. Parcelable 介面和Serializable 介面的區別?

Parcelable 介面是基於Android 源生的提供的序列化介面,Serializable 介面是基於Java 源生提供的序列化介面。都可以將資料持久化到本地。但是在開發中經常使用Serializable 介面,因為Parcelable介面需要實現兩個方法,writeToParcel 和readFromParcel,比較麻煩。但是Android 原始碼中會常用Parcelable介面,因為Parcelable 介面更輕量級一些,更符合Android 的特性。

Intent 也實現了Parcelable 介面。所以它可以將資料進行序列化和反序列化,並且可以開啟頁面,通過putExtra 將資料來回傳遞。

public class Intent implements Parcelable, Cloneable {
    // 省略程式碼
}

比如Person 大家都比較瞭解,Person 是對資料的封裝,它可以有name,age,sex 屬性,當我們需要通過intent 來傳遞Person 物件的時候,需要讓Person 實現Parcelable 介面,通過putExtra(String name,Parcelable value)方法來傳遞。

Android序列化:Serializable & Parcelable

Android視訊教程

相關推薦

Android序列序列

1. 什麼是java序列化,如何實現java序列化? 我們有時候將一個java物件變成位元組流的形式傳出去或者從一個位元組流中恢復成一個java物件,例如,要將java物件儲存到硬碟或者傳送給網路上的其他計算機,這個過程我們可以自己寫程式碼去把一個java物件

Android序列序列

這幾天在看到設計模式時,看到有關於序列化的知識,發現自己之前這塊知識很欠缺,所以這花了兩天仔細研究了一下,感覺這個東西還是很有趣的(當然也很有用-。+),今天給大家帶來這篇文章,希望對大家有幫助。序列化概念和應用首先我們需要知道序列化是個什麼意思。序列化:將物件轉換為可傳輸的

Java核心類庫-IO-對象流(實現序列序列

.get throws 反序 code row cts new java cep 使用對象流來完成序列化和反序列化操作:   ObjectOutputStream:通過writeObject()方法做序列化操作的   ObjectInputStream:通過readObje

Java IO-5 序列序列

str ride log getname file urn turn objects transient 建一個Person類 1 package demo05; 2 3 import java.io.Serializable; 4 5 public cla

契約類相關的序列序列

pub ima cti 相關 ria 數據 num spa set 契約類指繼承了:DataContract的類。契約類常在WCF,webService等各種服務中作為傳輸數據使用。 凡是契約類或者繼承了契約類的類,如果想要屬性參與序列化與反序列化,需要在屬性上加上標記:D

Java序列序列

setname [] 進制 方式 gets 創建 保存 ati 取數據 Java序列化與反序列化是什麽?為什麽需要序列化與反序列化?如何實現Java序列化與反序列化?本文圍繞這些問題進行了探討。 1.Java序列化與反序列化 Java序列化是指把Java對象轉換為字節序

asp.net mvc中如何處理字符串對象之間的序列序列(一)

osi strong 類結構 plain pbo edate inf esc arp 前臺我們一般用ajax來發送數據到後端進行處理,如果json數據結構和後臺的實體類結構一致,就直接可以反序列化為指定的對象進行操作,非常方便。 前端發送的json數據結構: 後端實體結

C#對象序列序列

space ros 個人信息 瀏覽器 特性 點名 文件名 屬性節點 派生 1.對象序列化的介紹 (1).NET支持對象序列化的幾種方式 二進制序列化:對象序列化之後是二進制形式的,通過BinaryFormatter類來實現的,這個類位於System.Runtime.Seri

Java將對象寫入文件讀出——序列序列

ansi print 成員 trace 對象的引用 ack lose 靜態 spa Java類中對象的序列化工作是通過ObjectOutputStream和ObjectInputStream來完成的。 寫入: 1 File aFile=new File(

畢業項目畢業 -- pickle序列序列操作

style import 使用 python pan 項目 imp 序列化 操作 Python可以使用pickle做序列化: 序列化示例: import picklewith open(‘les.pickle‘, ‘wb‘) as f: pickle.du

C#語言-08.序列序列

clas 本質 cnblogs 語法 信息 字段 使用 serializa col a. 序列化:是將對象的狀態存儲到特定存儲介質中的過程 i. 語法:public void Serialize(序列化過程的文件流,保存的對象)

Day4 閉包、裝飾器decorator、叠代器生成器、面向過程編程、三元表達式、列表解析生成器表達式、序列序列

反序 bsp pic nbsp tor 序列 space 列表解析 列表 http://pic.cnhubei.com/space.php?uid=1774&do=album&id=1362489http://pic.cnhubei.com/space.ph

01. Java對象的序列序列簡介

語音 log -c object height 通訊 圖片 二進制 進程    Java對象的序列化與反序列化 ; 給大家講解一下什麽是序列化 & 反序列化      當兩個進程進行遠程通訊的時候,彼此相互可以發送各種類型的數據,如文本,圖片,語音和視頻等無論是任何

如何使用 JSON for Modern C++ 序列序列號,換行符導致序列失敗

http gb2 elf ldp c++ spi ssp 使用 b16 W48z士5742i4鍁鉀http://shequ.docin.com/qbvl66336 6j夠裝何掖tj嘔蔡5VLhttp://tushu.docin.com/olybb166 渤k搶97L巳綱鋅7

單例模式序列序列

int nts 如果 mex res tac tor cep ios package com.wz.thread.resolve;import java.io.ObjectStreamException;import java.io.Serializable;/** * 序

python-序列序列

ret bject 通用 for pla nco ray 字典 read 序列化模塊# 序列化方法# 格式轉換# 把python中的數據轉換成str---序列化# 可以str轉換成python的數據---反序列化 json模塊 # json所有的語言都通用,它能序列化的數

模塊講解----json模塊(跨平臺的序列序列

/usr 列表 strong 序列化 類型轉換 min 字符 虛擬 json 一、json的特點 1、只能處理簡單的可序列化的對象;(字典,列表,元祖) 2、json支持不同語言之間的數據交互;(python - go,python - java) 二、使用場

【轉】C# 序列序列

使用 ria tle 輸入 == 必須 mls zab ddr 轉自:https://www.cnblogs.com/lsy131479/p/8371858.html 對象持久化到文本文件,策略是:將對象的屬性值打散,拆解,分別存儲。 序列化: 保存對象的"全景圖" 序

JSON序列序列

class a using demo pos define sys ali convert lose 1.add reference [System.Runtime.Serializatio] 2.using [System.Runtime.Serialization] a

C#序列序列

color bsp private start sys bin create body null 一、序列化: 1 public void SerilizeData() 2 { 3 FileStream fs =