序列化的两种实现及优劣比较

      序列化我们通常会用在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 CREATOR = new Creator() {

        /**
         * 供外部类反序列化本类数组使用
         */
        @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

你可能感兴趣的:(android进阶,android,对象)