1. 程式人生 > >Serializable和Parcelable的區別及使用方式

Serializable和Parcelable的區別及使用方式

物件在傳遞過程中必須進行序列化方可傳遞,android序列化有兩種方式,分別是繼承Serializable和Parcelable介面。兩種都是用於支援序列化、反序列化話操作,兩者最大的區別在於儲存媒介的不同,Serializable使用IO讀寫儲存在硬碟上,而Parcelable是直接在記憶體中讀寫,很明顯記憶體的讀寫速度通常大於IO讀寫,Serializable是java序列化介面,使用起來簡單但是開銷大序列化反序化都要進行大量的I/O操作,Parcelable是Android中的序列化方式,所以在Android中通常優先選擇Parcelable。平日開發中Serializable比較容易上手直接繼承介面即可,Parcelable使用較為複雜,但是效能高於Serializable十倍。

當物件序列化到儲存裝置或者通過網路傳輸的時候最好是使用Serializable,Parcelable也可以用做該過程,但是使用比較複雜所以建議使用Serializable。其他情況使用建議Parcelable

下面介紹Serializable的使用方式:

Serializable使用簡單。物件直接繼承該介面即可。

public class User implements Serializable{
    private int id;
    private String username;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

在傳參的時候使用intent或者是bundle。傳遞方式如下

Intent intent = new Intent(MainActivity.this,SecondActivity.class);
intent.putExtra("user",user);
Bundle bundle = intent.getExtras();
bundle.putSerializable("user1",user);
intent.putExtras(bundle);
startActivity(intent);

獲取方式如下:

Intent intent = getIntent();
Bundle bundle = intent.getExtras();
User user= (User) intent.getSerializableExtra("user");
User user1 = (User) bundle.getSerializable("user1");

接下來講一下Parcelable的使用,為了方便學習我把幾種常用的型別都寫上了:

這裡面很多方法都是系統生成的。大家自己寫上自己需要的構造器即可。這裡包括序列化和反序列化兩個方法,因此有新物件加入的時候兩個方法必須都寫上相應的過程。先簡單介紹以下幾個方法

public static final Creator<Teacher> CREATOR = new Creator<Teacher>() {
    @Override
    public Teacher createFromParcel(Parcel in) {
//從序列化的物件建立原始物件
        return new Teacher(in);
    }

    @Override
    public Teacher[] newArray(int size) {
//建立指定長度的原始陣列
        return new Teacher[size];
    }
};
返回當前物件的內容描述,如果含有檔案描述則返回1,否則返回0一般都返回0.
@Override
public int describeContents() {
    //固定寫法
    return 0;
}
從序列化的物件中建立原始物件即反序列化
protected Teacher(Parcel in) {
    //順序一定要對應上
    id = in.readInt();
    //讀取的String轉為布林型別
    normalStatus = Boolean.valueOf(in.readString());
    gmtCreated = in.readLong();
    name = in.readString();
    //讀取的price為String型別, 需要轉為BigDecimal
    price = new BigDecimal(in.readString());
    //讀取物件實現了Parcelable介面的物件
    secondBean = in.readParcelable(Student.class.getClassLoader());
    //讀取實現了Parcelable介面的物件List
    secondBeanList = in.readArrayList(Student.class.getClassLoader());
    //建立(讀取)int型別陣列, 其他陣列型別以此類推
    numberArray = in.createIntArray();
    map = in.readHashMap(String.class.getClassLoader());
}
序列化過程:
將當前物件寫入序列化結構中,其中flags有兩個值,0或1,當為1時標誌當前物件需要作為返回值返回,不能立即釋放資源。幾乎所有情況都為0;
@Override
public void writeToParcel(Parcel out, int flags) {
    //切記非常重要, 寫資料(out.write...)和下面的讀資料(in.read...)的順序一定要和宣告的屬性順序對應上, 不然會因為讀寫的資料型別不一致而報異常
    //普通資料型別int, double, String等等, 用法以此類推
    out.writeInt(id);
    //由於沒有寫入布林資料型別的方法, 需要把布林資料型別轉換為String
    out.writeString(String.valueOf(normalStatus));
    out.writeLong(gmtCreated);
    out.writeString(name);
    //判空, 因為如果price為null, 也會報異常, 沒有寫入BigDecimal的資料型別, 需要轉為String
    out.writeString(price == null ? "0" : price.toString());
    //寫入物件, 該物件必須也要實現Parcelable介面
    out.writeParcelable(secondBean, flags);
    //寫入List集合
    out.writeList(secondBeanList);
    //寫入int型別陣列, 其他的陣列型別以此類推
    out.writeIntArray(numberArray);
    out.writeMap(map);
}

明白這幾個過程後新增元素主要的操作是在序列化和反序列化的方法中即protected Teacher(Parcel in)和writeToParcel中

public class Teacher implements Parcelable {
    private int id;
    private boolean normalStatus;
    private long gmtCreated;
    private String name;
    private BigDecimal price;
    private Student secondBean;
    private List<Student> secondBeanList;
    private int[] numberArray;
    private Map<String,String> map;


    public Teacher() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isNormalStatus() {
        return normalStatus;
    }

    public void setNormalStatus(boolean normalStatus) {
        this.normalStatus = normalStatus;
    }

    public long getGmtCreated() {
        return gmtCreated;
    }

    public void setGmtCreated(long gmtCreated) {
        this.gmtCreated = gmtCreated;
    }

    public String getName() {
        return name;
    }

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

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public Student getSecondBean() {
        return secondBean;
    }

    public void setSecondBean(Student secondBean) {
        this.secondBean = secondBean;
    }

    public List<Student> getSecondBeanList() {
        return secondBeanList;
    }

    public void setSecondBeanList(List<Student> secondBeanList) {
        this.secondBeanList = secondBeanList;
    }

    public int[] getNumberArray() {
        return numberArray;
    }

    public void setNumberArray(int[] numberArray) {
        this.numberArray = numberArray;
    }

    public Map<String, String> getMap() {
        return map;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    //固定寫法, 只用修改Creator的泛型
    public static Creator<Teacher> getCREATOR() {
        return CREATOR;
    }

    //固定寫法, 只用修改Creator的泛型
    public static final Creator<Teacher> CREATOR = new Creator<Teacher>() {
        @Override
        public Teacher createFromParcel(Parcel in) {
            return new Teacher(in);
        }

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

    @Override
    public int describeContents() {
        //固定寫法
        return 0;
    }

    protected Teacher(Parcel in) {
        //順序一定要對應上
        id = in.readInt();
        //讀取的String轉為布林型別
        normalStatus = Boolean.valueOf(in.readString());
        gmtCreated = in.readLong();
        name = in.readString();
        //讀取的price為String型別, 需要轉為BigDecimal
        price = new BigDecimal(in.readString());
        //讀取物件實現了Parcelable介面的物件
        secondBean = in.readParcelable(Student.class.getClassLoader());
        //讀取實現了Parcelable介面的物件List
        secondBeanList = in.readArrayList(Student.class.getClassLoader());
        //建立(讀取)int型別陣列, 其他陣列型別以此類推
        numberArray = in.createIntArray();
        map = in.readHashMap(String.class.getClassLoader());
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        //切記非常重要, 寫資料(out.write...)和下面的讀資料(in.read...)的順序一定要和宣告的屬性順序對應上, 不然會因為讀寫的資料型別不一致而報異常
        //普通資料型別int, double, String等等, 用法以此類推
        out.writeInt(id);
        //由於沒有寫入布林資料型別的方法, 需要把布林資料型別轉換為String
        out.writeString(String.valueOf(normalStatus));
        out.writeLong(gmtCreated);
        out.writeString(name);
        //判空, 因為如果price為null, 也會報異常, 沒有寫入BigDecimal的資料型別, 需要轉為String
        out.writeString(price == null ? "0" : price.toString());
        //寫入物件, 該物件必須也要實現Parcelable介面
        out.writeParcelable(secondBean, flags);
        //寫入List集合
        out.writeList(secondBeanList);
        //寫入int型別陣列, 其他的陣列型別以此類推
        out.writeIntArray(numberArray);
        out.writeMap(map);
    }
}

Parcelable序列化必須保證裡面的物件都能序列化,改物件中包含Student,這個物件也必須是繼承Parcelable序列化的:

public class Student implements Parcelable {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Student() {
    }

    public Student(int id) {
        this.id = id;
    }

    protected Student(Parcel in) {
        id = in.readInt();
    }

    public static final Creator<Student> CREATOR = new Creator<Student>() {
        @Override
        public Student createFromParcel(Parcel in) {
            return new Student(in);
        }

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

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

    @Override
    public void writeToParcel(Parcel out, int flag) {
        out.writeInt(id);
    }

    public static Creator<Student> getCREATOR() {
        return CREATOR;
    }
}

傳參的過程如下:

Intent intent = new Intent(FirstParcelableActivity.this,SecondParcelableActivity.class);
intent.putExtra("parcelable",mainBean);
Bundle bundle = intent.getExtras();
bundle.putParcelable("parcelable1",mainBean);
intent.putExtras(bundle);
startActivity(intent);

獲得資料的過程如下:

Intent intent = getIntent();
Teacher mainBean = intent.getParcelableExtra("parcelable");
Bundle bundle = getIntent().getExtras();
Teacher mainBean1 = bundle.getParcelable("parcelable1");

相關推薦

Intent傳遞物件——SerializableParcelable區別

Intent在不同的元件中傳遞物件資料的應用非常普遍。下面介紹兩種通過Intent傳遞物件的方法。 1、實現Serializable介面 2、實現Parcelable介面 為什麼要將物件序列化?  1、永久性儲存物件,儲存物件的位元組序列到本地檔案中;  2、用

SerializableParcelable區別使用方式

物件在傳遞過程中必須進行序列化方可傳遞,android序列化有兩種方式,分別是繼承Serializable和Parcelable介面。兩種都是用於支援序列化、反序列化話操作,兩者最大的區別在於儲存媒介的不同,Serializable使用IO讀寫儲存在硬碟上,而Parcelab

實現序列化的兩種方式SerializableParcelable

Serializable       Serializable是Java所提供的一個序列化介面,它是一個空介面,為物件提供標準的序列化和反序列化操作        libcore/ojluni/src/main/java/java/io/Serializable.java

淺談Android中SerializableParcelable使用區別

Android中序列化有兩種方式:Serializable以及Parcelable。其中Serializable是Java自帶的,而Parcelable是安卓專有的。 一、Serializable序列化 serializable使用比較簡單,只需要對某個類實現Serializable 介面即可。 Ser

Android中兩種序列化方式的比較SerializableParcelable

Serializable和Parcelable介面可以完成物件的序列化過程, 序列化 (Serialization)將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以通過從儲存區中讀取或反序列化物件的狀態

Android 進階6:兩種序列化方式 Serializable Parcelable

什麼是序列化 我們總是說著或者聽說著“序列化”,它的定義是什麼呢? 序列化 (Serialization)將物件的狀態資訊轉換為可以儲存或傳輸的形式的過程。在序列化期間,物件將其當前狀態寫入到臨時或永續性儲存區。以後,可以通過從儲存區中讀取或反序列化物

Intent傳遞對象——SerializableParcelable差別

討論 保存數據 fault 反序列化 進行 生成 場景 設備 pan 前兩篇文章討論了Serializable和Parcelable實現Intent之間傳遞對象和對象數組的方式。兩種方法實現上相似,效果一致,怎麽選擇用哪種方法實現呢? Intent在不同的組件中傳遞對象

java android 序列號serializableparcelable

exceptio 對象的引用 undle ktr 實現原理 輸出 fin 使用 讀者 why 為什麽要了解序列化?—— 進行Android開發的時候,無法將對象的引用傳給Activities或者Fragments,我們需要將這些對象放到一個Intent或者Bundle裏面,

SerializableParcelable的簡單介紹

重新 出現 ray listen android lee long tag cti   Serializable和Pacelable接口可以完成對象的序列化過程,當我們需要通過Intent和Binder傳輸數據時就需要使用Parcelable或者Serializable。

.net core學習筆記《sdkruntime區別使用CLI在Ubuntu上快速搭建Console,WebApi,MVC三大應用模型》

img 裝包 new 來看 tin console bubuko file 接下來 一、需要安裝的軟件 1、虛擬機安裝Ubuntu系統(本人用的是vmware-14.1.12和buntu-18.04) 2、Xshell或 Putty(連接ssh服務) 3、FileZilla

mysql :==的區別統計查詢結果行號

變數初始化:@rownum:=0 累加,標記行號:@rownum:[email protected]+1 SELECT rank FROM ( SELECT id, @rownum := CAST(@rownum AS SIGNED) + 1 AS rank

Android中SerializableParcelable序列化物件詳解

學習內容: 1.序列化的目的 2.Android中序列化的兩種方式 3.Parcelable與Serializable的效能比較 4.Android中如何使用Parcelable進行序列化操作 5.Parcelable的工作原理 6.相關例項   1.序列化

getRequestDispatcher sendRedirect區別路徑問題

轉載自:https://www.cnblogs.com/w-wfy/p/6387538.html getRequestDispatcher 和sendRedirect區別   getRequestDispatcher是伺服器內部跳轉,位址列資訊不變,只能跳轉到web應用內的網頁

說說&&& |||的區別 關於位操作符的使用總結

參考資料: 張孝祥老師整理的Java就業面試題大全 Java開發實戰經典(李興華老師) 及http://hi.baidu.com/onjee/blog/item/4e902d1f3450040f304e15ca.html package src;/** 本示例演示&和&

【python】第一日 python2python3區別 命名方式 三種結構

一、python2和python3區別 1)print 語句區別   python2:print是個class,所以可以不用加括號,print 1,2+3   python3:print是個內建函式,必須加括號,print(1,2+3,end=" ") 2)input區別   python2:inp

Android SerializableParcelable序列化物件詳解

轉載:https://www.cnblogs.com/yezhennan/p/5527506.html 學習內容: 1.序列化的目的 2.Android中序列化的兩種方式 3.Parcelable與Serializable的效能比較 4.Android中如何使用Parcelabl

Serializable Parcelable

turn 標準 stat write @override color div fin create 序列化:將對象轉換為可以傳輸的二進制流的過程。 Serializable是 Java 提供的一個標準化的序列化接口。 Parcelable是 Android 提供的序列化接口

FC 13.2 使用Intent傳遞物件(SerializableParcelable

使用Intent的putExtra方法可以傳遞資料,但是不能直接來傳遞自定義的物件。接下來學習兩種床底物件的方式 Serializable方式 Parcelable方式 兩種方式的詳細講解   Serializable方式 Serializable是序

js中!!!的區別用法簡介

js中!的用法是比較靈活的,它除了做邏輯運算常常會用!做型別判斷,可以用!與上物件來求得一個布林值, 1、!可將變數轉換成boolean型別,null、undefined和空字串取反都為false,其餘都為true。 複製程式碼 1 !null=true 2 3

is==的區別,編碼相關內容總結

is和==的區別 is 比較的是記憶體地址 == 比較的是內容 當兩個變數指向同一個物件的時候. is是True, ==也是True 編碼   1. ascii. 有: 數字, 字母, 特殊字元. 8bit 1byte 128 最前面是0 2. gbk. 包含: ascii, 中文(主要),