欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android序列化之Parcelable和Serializable的使用詳解

 更新時間:2018年01月02日 10:51:28   作者:Jdqm  
本篇文章主要介紹了Android序列化之Parcelable和Serializable的使用詳解,具有一定的參考價值,感興趣的小伙伴們可以參考一下

序列化與反序列

首先來了解一下序列化與反序列化。

序列化

由于存在于內(nèi)存中的對象都是暫時的,無法長期駐存,為了把對象的狀態(tài)保持下來,這時需要把對象寫入到磁盤或者其他介質(zhì)中,這個過程就叫做序列化。

反序列化

反序列化恰恰是序列化的反向操作,也就是說,把已存在在磁盤或者其他介質(zhì)中的對象,反序列化(讀?。┑絻?nèi)存中,以便后續(xù)操作,而這個過程就叫做反序列化。

概括性來說序列化是指將對象實例的狀態(tài)存儲到存儲媒體(磁盤或者其他介質(zhì))的過程。在此過程中,先將對象的公共字段和私有字段以及類的名稱(包括類所在的程序集)轉(zhuǎn)換為字節(jié)流,然后再把字節(jié)流寫入數(shù)據(jù)流。在隨后對對象進行反序列化時,將創(chuàng)建出與原對象完全相同的副本。

實現(xiàn)序列化的必要條件

一個對象要實現(xiàn)序列化操作,該類就必須實現(xiàn)了Serializable接口或者Parcelable接口,其中Serializable接口是在java中的序列化抽象類,而Parcelable接口則是android中特有的序列化接口,在某些情況下,Parcelable接口實現(xiàn)的序列化更為高效,關(guān)于它們的實現(xiàn)案例我們后續(xù)會分析,這里只要清楚知道實現(xiàn)序列化操作時必須實現(xiàn)Serializable接口或者Parcelable接口之一即可。

序列化的應用情景

主要有以下情況(但不限于以下情況)

1)內(nèi)存中的對象寫入到硬盤;
2)用套接字在網(wǎng)絡上傳送對象;
3)通過RMI(Remote Method Invoke 遠程方法調(diào)用)傳輸對象;

1.Parcelable和Serializable有什么用,它們有什么差別?

Parcelable和Serializable是兩個接口,它們的作用是讓實現(xiàn)了其中一個接口的類的對象能夠被序列化和反序列化。

(1)Serializable是java提供的序列化接口,它是一個空的接口,僅標識該類型可序列化的,具體的序列化/反序列化工作由 ObjectInputStream(readObject)/ObjectOutputStream(writeObject) 完成,這個過程包含大量的I/O操作,使用比較簡單,但需要考量性能的影響。使用場景:將對象持久化到存儲介質(zhì)或者通過網(wǎng)絡傳輸。

(2)Parcelable接口是Android平臺下的序列化接口,通??邕M程傳遞的數(shù)據(jù)都要正確實現(xiàn)這個接口,比如Intent,Bitmap等。Parcelable實現(xiàn)起來比Serializable復雜,但性能較好。使用場景:在內(nèi)存中實現(xiàn)序列化,例如跨進程傳遞。若某個字段不需要序列化,在實現(xiàn) writeToParcel 方法中忽略此字段即可。

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

(1)首先實現(xiàn)Parcelable接口,并實現(xiàn)接口中的方法。

/**
 * 返回當前對象的內(nèi)容描述,如果有文件描述符返回1,否則返回0。
 */
@Override
public int describeContents() {
 return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
 dest.writeInt(userId);
 dest.writeString(userName);
 dest.writeInt(isMan ? 1 : 0);
}

(2)接著創(chuàng)建一個Parcelable接口內(nèi)部的接口類型Creator的一個成員,內(nèi)部需要用到一個帶一個Parcel參數(shù)的構(gòu)造方法。

protected User(Parcel in) {
 userId = in.readInt();
 userName = in.readString();
 isMan = in.readByte() != 0;
}

/**
 * 在aidl中,參數(shù)使用in或者inout來修飾時,服務端的onTransact()會調(diào)用CREATOR中方法來反序列化客戶端傳過來的參數(shù)
 */
public static final Creator<User> CREATOR = new Creator<User>() {
 @Override
 public User createFromParcel(Parcel in) {
  return new User(in);
 }

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

(3)如果在aidl文件中使用out或者inout定向tag來修飾參數(shù),還必須實現(xiàn)一個 readFromParcel(Parcel) 方法,這是因為使用這兩個定向tag修飾的參數(shù),在服務端onTransact()返回后,客戶端會調(diào)用 readFromParcel() 來讀取(反序列化)_reply中的數(shù)據(jù)。該方法與writeToParcel是對應的,實現(xiàn)如下:

public void readFromParcel(Parcel in) {
 userId = in.readInt();
 userName = in.readString();
 isMan = in.readInt() == 1 ? true : false;
}

3.實現(xiàn)Serializable接口

通過實現(xiàn)Serializable接口來實現(xiàn)序列化比較簡單,只需要實現(xiàn)該接口,并指定 serialVersionUID 即可,當然這個ID是可選的,可以不手動指定。通過ObjectIntputStream /ObjectOutputStream來序列化和反序列化。

ObjectOutputStream oos = null;
try {
 oos = new ObjectOutputStream(new FileOutputStream(new File("sdcard/user.cache")));
 User user = new User(111, "Jdqm", true);
 oos.writeObject(user);
} catch (IOException e) {
 e.printStackTrace();
} finally {
 try {
  oos.close();
 } catch (IOException e) {
  e.printStackTrace();
 }
}
ObjectInputStream ois = null;
try {
 ois = new ObjectInputStream(new FileInputStream(new File("sdcard/user.cache")));
 User user = (User) ois.readObject();
 Log.d(TAG, "user: " + user);
} catch (IOException | ClassNotFoundException e) {
 e.printStackTrace();
} finally {
 try {
  ois.close();
 } catch (IOException e) {
  e.printStackTrace();
 }
}

輸出結(jié)果

User{userId=111, userName='Jdqm', isMan=true}

serialVersionUID的意義:輔助完成序列化和反序列化,當一個類實現(xiàn)SerSerializable接口,沒有添加serialVersionUID的作用字段時,IDE會發(fā)出警告,這個字段可以手動指定一個值,比如1L,也可指定為IED根據(jù)類的結(jié)構(gòu)生成一個long值,它們的效果是一樣的。在序列化時會將這個值寫入存儲介質(zhì),反序列化時就校驗本地類的serialVersionUID和序列化介質(zhì)中的是否一致,不一致將拋出異常 java.io.InvalidClassException

(1)若不指定:系統(tǒng)會根據(jù)類的結(jié)構(gòu)計算出一個serialVersionUID,一旦類的結(jié)構(gòu)發(fā)生改變這個值就會改變,將導致反序列化失?。?/p>

(2)指定一個值:當類的結(jié)構(gòu)發(fā)生改變時,也可以不修改serialVersionUID的值,這種情況下能最大程度上通過反序列化回復數(shù)據(jù),若類的結(jié)構(gòu)發(fā)生毀滅性的改變,例如字段數(shù)據(jù)類型改變了,也會導致反序列失敗。

Note: 類的結(jié)構(gòu)發(fā)生改變指的是類的成員變量的改變,添加一個普通的方法是不會導致計算得到的serialVersionUID改變的。構(gòu)造方法、toString()、getter/setter改變會引起serialVersionUID改變。

  1. transient修飾的成員變量不參與序列化,反序列化時改成員為該數(shù)據(jù)類型的默認值
  2. 靜態(tài)成員不參與序列化
  3. 反序列化得到的一個新對象的過程并沒有調(diào)用構(gòu)造方法

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android 動態(tài)添加view或item并獲取數(shù)據(jù)的實例

    Android 動態(tài)添加view或item并獲取數(shù)據(jù)的實例

    下面小編就為大家?guī)硪黄狝ndroid 動態(tài)添加view或item并獲取數(shù)據(jù)的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • Android RecyclerView添加FootView和HeadView

    Android RecyclerView添加FootView和HeadView

    這篇文章主要介紹了Android RecyclerView添加FootView和HeadView的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Android 中的危險權(quán)限詳細整理

    Android 中的危險權(quán)限詳細整理

    這篇文章主要介紹了Android 中的危險權(quán)限詳細整理的相關(guān)資料,Android 中有上百種權(quán)限,現(xiàn)在將所有的權(quán)限歸為兩類,一類是普通權(quán)限,一類的危險權(quán)限,危險權(quán)限則表示那些可能會觸及到用戶安全隱私或者對設備安全造成影響的權(quán)限,需要的朋友可以參考下
    2017-07-07
  • Android自定義View實現(xiàn)縱向跑馬燈效果詳解

    Android自定義View實現(xiàn)縱向跑馬燈效果詳解

    對于跑馬燈效果在我們?nèi)粘J褂玫腶pp中還是很常見的,比如外賣app的商家公告就使用了此效果,但是它是橫向滾動的,橫向滾動多適用于單條信息;但凡涉及到多條信息的滾動展示,用縱向滾動效果會有更好的用戶體驗,今天我們通過自定義View來看看如何實現(xiàn)縱向跑馬燈效果。
    2016-11-11
  • Android Oss上傳圖片的使用示例

    Android Oss上傳圖片的使用示例

    本篇文章主要介紹了Android Oss上傳圖片的使用示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Android實現(xiàn)網(wǎng)易新聞客戶端首頁效果

    Android實現(xiàn)網(wǎng)易新聞客戶端首頁效果

    這篇文章主要為大家詳細介紹了Android實現(xiàn)網(wǎng)易新聞客戶端首頁效果的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • android調(diào)用原生圖片裁剪后圖片尺寸縮放的解決方法

    android調(diào)用原生圖片裁剪后圖片尺寸縮放的解決方法

    這篇文章主要為大家詳細介紹了android調(diào)用原生圖片裁剪后圖片尺寸縮放的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Android編程實現(xiàn)的短信編輯器功能示例

    Android編程實現(xiàn)的短信編輯器功能示例

    這篇文章主要介紹了Android編程實現(xiàn)的短信編輯器功能,涉及Android權(quán)限控制、界面布局及短信功能相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Android判斷網(wǎng)絡狀態(tài)的代碼

    Android判斷網(wǎng)絡狀態(tài)的代碼

    這篇文章主要為大家詳細介紹了Android判斷網(wǎng)絡狀態(tài)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android WebView開發(fā)之WebView與Native交互

    Android WebView開發(fā)之WebView與Native交互

    隨著H5的廣泛使用,Android開發(fā)過程中免不了會使用網(wǎng)頁來做展示,那么web與native之間的通信就顯得尤其重要了,其實際上是JavaScript與java之間的通信。本文將為大家詳細介紹二者是如何實現(xiàn)交互的,需要的朋友可以參考一下
    2021-12-12

最新評論