Serializable和Parcelable在Android中传递值对象时的使用粗略讲解

来源:互联网 发布:mysql slave status 编辑:程序博客网 时间:2024/05/01 18:54

在Android中,我们会频繁地使用到值传递Intent、Bundle,有时候传递的是int或者String等系统提供的值类型,但有时候要传递自定义的类型,比如用户User。这时我们就要用到Serializable或者Parcelable用于对自定义数据进行序列化

两者区别:
Serializable:是Java提供的序列化接口,所有序列化操作由系统完成,方便但是速度比较慢,效率低。

Parcelable:是Android提供的序列化接口,需要手动完成部分操作(操作详细见下面内容),有些许复杂但是速度快,效率高


实现Parcelable就是为了进行序列化,那么,为什么要序列化?

1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
4)选择序列化方法的原则


注意

1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
4)需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口。

————————————————

User自定义类代码:

public class User {    private String userName;    private int userAge;    public String getUserName(){        return userName;    }    public void setUserName(String userName){        this.userName = userName;    }    public int getUserAge(){        return userAge;    }    public void setUserAge(int userAge){        this.userAge = userAge;    }}

————————————————

Serializable传递User值对象的代码:
首先User类要实现Serializable接口(public class User implements Serializable)

put:    Intent i = new Intent(......);    User user = new User();    user.setUserName("zhangsan");    user.setUserAge("11");    i.putExtra("user",user);get:    Intent i = getIntent();    User user = (User) i.getSerializableExtra("user");    System.out.println(user.getUserName());

————————————————

Parceliable传递User值对象的代码:
首先User类要实现Parceliable接口,并且Override两个方法describeContents()、writeToParcel(),还需要在类中添加一个静态成员变量CREATOR,这个变量需要实现 Parcelable.Creator 接口。

简言之:通过writeToParcel将你的对象映射成Parcel对象,再通过createFromParcel将Parcel对象映射成你的对象。也可以将Parcel看成是一个流,通过writeToParcel把对象写到流里面,再通过createFromParcel从流里读取对象,只不过这个过程需要你来实现,写的顺序和读的顺序必须一致

  public class User implements Parceliable{      ......    @Override    public int describeContents(){   //这个不用管        return 0;    }    @Override    public void writeToParcel(Parcel dest , int flags){        dest.writeString(getUserName());        dest.writeString(getUserAdd());        dest.writeInt(getUserAge());    }    public static final Creator<User> CREATOR = new Creator<User>{        @Override        public User createFromParcel(Parcel source){            User user = new User();            user.setUserName(source.readString());            user.setUserAdd(source.readString());            user.setUserAge(source.readInt());            return user;          }        @Override        public User[] newArray(int size){            return new User[size];        }    }}   

下面是将Uesr对象进行传递的代码

put:     User user = new User();     user.setUserName("zhangsan");     user.setUserAdd("shagnhai");     user.setUserAge(11);     Intent i = new Intent(......);     i.putExtra("user",user);get:    Intent i = getIntent();    User user = i.getParcelableExtra("user");    System.out.println(user.getUserName());

注:其中public static final一个都不能少,内部对象CREATOR的名称也不能改变,必须全部大写。需重写本接口中的两个方法:createFromParcel(Parcel in) 实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层,newArray(int size) 创建一个类型为T,长度为size的数组,仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。

————————————————

从上面的代码我们可以看到,Serializable和Parcelable的区别主要是对自定义数据进行处理。

0 0