序列化和反序列化是跨进程通信的基础。其存在的意义在于,可把自定义类转化为某种公认的存储格式进行传输,并保证传输前后自定义类的可解析性。

对于Android来说,存在两者实现方式,Serializable和Parcelable。Serializable是java自带的接口。而Parcelable是Android专门提供的接口。我们在Intent中传递Bundle数据就实现了Parcelable接口。

Serializable

Serializable使用起来非常简单,只需要将自定义类implements Serializable即可,且没有任何需要实现的方法。

举个简单的例子

public class User implements Serializable{    private static final long serialVersionUID=1l;    private String mName;    private int mAge;    public User(String mName, int mAge) {        this.mName = mName;        this.mAge = mAge;    }    public String getmName() {        return mName;    }    public int getmAge() {        return mAge;    }    public void setmName(String mName) {        this.mName = mName;    }    public void setmAge(int mAge) {        this.mAge = mAge;    }}

注意到类中存在serialVersionUID字段,该变量是optional的。区别在于,

(1)如果不设定,在序列化时,将自动添加该字段,并把类结构的Hash赋值给该字段。当反序列化时,对比Hash,若一致,则解析,不一致,则抛出异常。

(2)如果设定,在反序列化出现异常时(例如,添加或删除了某些字段),最大程度的完成对数据的解析,若仍不可解析,则抛出异常。

Parcelable

Parcelable接口相对Serializable要复杂些,需要完成对几个方法的实现。直接来看个例子。

public class User implements Parcelable {    private String mName;    private int mAge;    public User(String mName, int mAge) {        this.mName = mName;        this.mAge = mAge;    }    protected User(Parcel in) {        mName = in.readString();        mAge = in.readInt();    }    public static final Creator CREATOR = new Creator() {        @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;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeString(mName);        dest.writeInt(mAge);    }    public String getmName() {        return mName;    }    public int getmAge() {        return mAge;    }    public void setmName(String mName) {        this.mName = mName;    }    public void setmAge(int mAge) {        this.mAge = mAge;    }}

(1)describeContents()方法,用于表述。通常不用修改,直接返回0。

(2)public void writeToParcel(Parcel dest, int flags)方法,用于将自定义类进行序列化。

(3)protected User(Parcel in)构造方法,用于反序列化,将序列化数据解析为自定义类。

(4)Parcelable.Creator字段,实际是对protected User(Parcel in)构造方法的调用,用于从序列化数据中转化自定义类。

需要注意的是writeToParcel中的字段写入顺序,要与protected User(Parcel in)中的字段读取顺序一致,否则将解析失败。

对比

从实现上来看,Parcelable比Serializable繁琐。但如果使用Android Studio自动生成的话,倒也无所谓。

从效率上来说,Parcelable为Android专用,效率高,而Serializable会调用大量的IO接口,开销大。

从适用场景来说,Parcelable多运用于进程间的数据传递,而Serializable更适用于以文件为载体的网络传输。

附录

附带Serializable读取和写入例子

public void writeSerializable() {    try {        // 构造对象        User user = new User("breakloop",1);        // 构造序列化输出字节流        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("xxx.txt"));        // 序列化对象        oos.writeObject(book);        // 关闭流        oos.close();    } catch (Exception e) {        e.printStackTrace();    }}public void readSerializable() {    try {        // 创建序列化读取字节流        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("xxx.txt"));        // 反序列化(读取)对象        User user = (User) ois.readObject();        // 关闭流        ois.close();    } catch (Exception e) {        e.printStackTrace();    }}

更多相关文章

  1. Android四大基本组件(Activity,Service,Content Provider 和 Broadc
  2. Android原生和H5、JS交互,使用JsBridge
  3. iOS开发之分页控件的简单封装
  4. 如何在Android中利用AIDL添加service
  5. Android(Xamarin)之旅(五)
  6. Android(安卓)invalidate 与postInvalidate用法
  7. Android中Intent,service,broadcast应用浅析
  8. Android事件分发与消费
  9. Android(安卓)图片压缩也即生成缩略图方法

随机推荐

  1. Android多媒体开发高级编程
  2. Android(安卓)根据坐标获取地址
  3. 2011.07.20——— android 获得当前view
  4. Android(安卓)studio 3.1.3 无法获取pom
  5. Android中使用log4j
  6. android获取系统wifi状态等
  7. 读取android根目录下的文件或文件夹
  8. 非UI线程可不可以更新UI(一)
  9. Android(安卓)Studio Settings Repositor
  10. Android(安卓)Stuido 更新问题