序列化的兩種實現及優劣比較

      序列化我們通常會用在Activity之間進行對象傳遞的時候使用到,那麼序列化有兩種,Serializable和Parcelable ,我們該選擇哪一種呢?那就要先知道兩種區別。

      1、作用

      Serializable的作用是爲了保存對象的屬性到本地文件、數據庫、網絡流、rmi以方便數據傳輸,當然這種傳輸可以是程序內的也可以是兩個程序間的。而Android的Parcelable的設計初衷是因爲Serializable效率過慢,爲了在程序內不同組件間以及不同Android程序間(AIDL)高效的傳輸數據而設計,這些數據僅在內存中存在,Parcelable是通過IBinder通信的消息的載體。

從上面的設計上我們就可以看出優劣了。

      2、效率及選擇

      Parcelable的性能比Serializable好,在內存開銷方面較小,所以在內存間數據傳輸時推薦使用Parcelable,如activity間傳輸數據,而Serializable可將數據持久化方便保存,所以在需要保存或網絡傳輸數據時選擇Serializable,因爲android不同版本Parcelable可能不同,所以不推薦使用Parcelable進行數據持久化

      3、編程實現

      對於Serializable,類只需要實現Serializable接口,並提供一個序列化版本id(serialVersionUID)即可。而Parcelable則需要實現writeToParcel、describeContents函數以及靜態的CREATOR變量,實際上就是將如何打包和解包的工作自己來定義,而序列化的這些操作完全由底層實現。

這裏有個需要注意一下,就是這個序列化版本id,很多人使用的時候感覺這個東西是可有可無的,但是我們是需要寫上的,具體的原因可參考這篇文章:http://blog.csdn.net/bornlili/article/details/55210527

      然後接下來就是實現了,首先實現Serializable.
      這個的實現是何其的簡單,只要繼承一下和聲明一個序列化版本id即可,然後就可以放到bundle裏面使用了,給出;例子:

mport java.io.Serializable;

/**
 * Created by 2381144912 on 2017/09/22.
 */

public class newPerson implements Serializable{

    private String name;
    private int age;
    private static final long serialVersionUID = 1L;   //序列化id

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

}

使用時:

                person = new Person("小明", "小強", 10);
                Intent intent = new Intent(MainActivity.this, SecondActivity.class);
                Bundle bundle = new Bundle();
                bundle.putParcelable("Person", person);
                intent.putExtras(bundle);
                startActivity(intent);

然後接受:


        Person person =  getIntent().getExtras().getParcelable("Person");
        Toast.makeText(this, "" + person.getNickname() + person.getUsername() + person.getAge(), Toast.LENGTH_SHORT).show();

      好了,第一種實現了,下面開始Parcelable的實現,這個對前面的來說要重寫幾個方法即可,給出實例:

/**
 * Created by 23811 on 2017/09/22.
 */

public class Person implements Parcelable {

    private String username;
    private String nickname;
    private int age;

    public Person() {
        super();
    }

    public Person(String username, String nickname, int age) {
        super();
        this.username = username;
        this.nickname = nickname;
        this.age = age;
    }

    public String getUsername() {
        return username;
    }

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

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    /**
     * 這裏的讀的順序必須與writeToParcel(Parcel dest, int flags)方法中
     * 寫的順序一致,否則數據會有差錯,比如你的讀取順序如果是:
     * nickname = source.readString();
     * username=source.readString();
     * age = source.readInt();
     * 即調換了username和nickname的讀取順序,那麼你會發現你拿到的username是nickname的數據,
     * 而你拿到的nickname是username的數據
     *
     * @param source
     */
    public Person(Parcel source) {
        username = source.readString();
        nickname = source.readString();
        age = source.readInt();
    }

    /**
     * 這裏默認返回0即可
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 把值寫入Parcel中
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(username);
        dest.writeString(nickname);
        dest.writeInt(age);
    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {

        /**
         * 供外部類反序列化本類數組使用
         */
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }

        /**
         * 從Parcel中讀取數據
         */
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }
    };

}

註釋很詳細,需要注意的就是我們按什麼順序讀進去的,就要按什麼順序讀出來,否則會亂套,然後是使用:

                newPerson = new newPerson("小明", 10);
                Intent intent1 = new Intent(MainActivity.this, ThirdActivity.class);
                Bundle bundle1 = new Bundle();
                bundle1.putSerializable("newPerson", newPerson);
                intent1.putExtras(bundle1);
                startActivity(intent1);

最後接收:

        newPerson person =  (newPerson) getIntent().getExtras().getSerializable("newPerson");
        Toast.makeText(this, "" + person.getName() +  person.getAge(), Toast.LENGTH_SHORT).show();

      到這大家應該對序列化比較瞭解了,其實就是爲了方便數據的傳遞而給我們的對象添加了規則而已,最後給出Demo:http://download.csdn.net/download/wanxuedong/9990322

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章