天天看點

Android序列化:Parcelable

一、概述

在上一篇中我們介紹了Java中的序列化方式(也能用于Android),詳情:Java Serializable(序列化),本篇繼續介紹Android中特有的序列化方式:Parcelable,它也是一個接口,隻要實作這個接口,一個類的對象就可以實作序列化并可以通過Intent和Binder傳遞。

Parcelable是Android中進行跨程序間通信傳遞資料的方式,它基于記憶體進行序列化和反序列化,是以效率較高。Parcelable定義了将資料寫入Parcel,和從Parcel中讀出資料的接口。一個實體(用類來表示),如果需要封裝到消息中去,就必需實作這一接口。其中Parcel的作用:它提供一套機制,可以将序列化之後的資料寫入到一個共享記憶體中,其他程序通過Parcel可以從這塊共享記憶體中讀取出位元組流,并反序列化成對象。

二、Parcelable接口定義

public interface Parcelable {
    // 内容描述接口,很少用到
    public int describeContents();
    // 序列化
    public void writeToParcel(Parcel dest, int flags);
    // 反序列化,目的是要從Parcel中構造一個實作了Parcelable的類的執行個體處理。
    // 因為實作類在這裡還是不可知的,是以利用模闆參數,類名通過模闆參數傳入。
    // 為了能夠實作模闆參數的傳入,這裡定義Creator嵌入接口,内含兩個接口函數分别傳回單個和多個繼承類執行個體。
    public interface Creator<T> 
    {
           public T createFromParcel(Parcel source);
           public T[] newArray(int size);
    }
}
           

三、應用Parcelable

public class User implements Parcelable {
    public String name;
    public int age;

    private User(Parcel in) {
        // 按照寫入的順序依次從Parcel中恢複對象字段值
        name = in.readString();
        age = in.readInt();
    }

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 反序列化過程(從Parcel讀取資料)
    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];
        }
    };

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

    // 序列化過程(将資料寫入Parcel)
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // 将各個字段按照順序寫入流中
        dest.writeString(name);
        dest.writeInt(age);
    }
}
           

以下是測試Activity

public class TestActivity extends Activity {
    private static final String TAG = TestActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);

        Parcel parcel = Parcel.obtain();
        User user = new User("aronchen", 28);
        //寫入Parcel
        parcel.writeParcelable(user, 0);
        //Parcel讀寫共用一個位置計數,這裡一定要重置一下目前的位置
        parcel.setDataPosition(0);
        //讀取Parcel
        User user1 = parcel.readParcelable(User.class.getClassLoader());
        Log.e(TAG, "user.name:" + user1.name + "; user.age:" + user1.age);
    }

}
           

可以看出,使用Parcelable接口稍微麻煩點,和Serializable相比,我們需要在writeToParcel中按序将各個字段寫入到流中,同樣,在createFromParcel中我們需要自己傳回一個User對象。其中的CREATOR用到了代理設計模式。

三、Parcelable與Serializable的差別

Serializable Parcelable
Java SE、Android通用 Android專用
需要大量I/O操作,效率低 記憶體序列化,效率高
使用較友善 使用較複雜

繼續閱讀