Android进程通信之一:两种序列化方式

2月下旬辞职了,去海南度假到现在,领略了一把三亚风情也算任性和这里写图片描述

然而这样任性带来的后果就是。。不行了我必须吐槽一句。。

没毕业的找工作就这么难嘛!投了57家一家面试机会都没有,好歹给个面试机会啊!!本宝宝不开心!!

不知道其他没有毕业的童鞋是不是也是这种遭遇呢,难道真的是寒冬。。 其实还是自己能力不够。。不过别灰心,只要自己足够努力,迟早会有工作的(标标居然建议我先去端盘子????妈蛋)。

牢骚完毕,为了更好地提升自己,赶紧翻开了主席的《开发艺术探索》,开始学习今天的内容。在说Messanger之前呢,先有必要说说Android中的序列化。

序列化的两种方式

在Android中有两种序列化方式,Serializable(原谅我到现在都不会拼写。。)和Parcelable。其中Serializable是java提供的,而Parcelable是Android独有的。

两种序列化的不同:
Parcelable的效率高,但是使用麻烦,主要用于内存序列化。
Serializable使用简单,但是需要做大量的I/O操作,开销很大,适用于储存设备,或者网络传输。

Serializable的使用

Serializable的使用及其简单,只要实现Serializable接口即可。
在用ObjectOutputStream和ObjectInputStream即可进行序列化操作,举个栗子:

public class Goods implements Serializable{
    private int mId;

    public Goods(int id){
        mId = id;
    }

    public int getmId() {
        return mId;
    }
}
 Goods goods = new Goods(3);

        //序列化
        try {
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/sdcard/test.txt"));
            oos.writeObject(goods);
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //反序列化
        try {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/sdcard/test.txt"));
            Goods goodsIn = (Goods)ois.readObject();
            ois.close();
            Log.e("wing",goodsIn.getmId()+"");
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

这时,可以看到控制台输出了id 为3。

需要指出的一点是,为了保证序列化的正确性,应该给Goods类添加一个序列化UID。即serialVersionUID。这里用户可以自定义,主要是类的版本检验,在反序列化过程中,如果这个id值不一致,则反序列化失败。

private static final long serialVersionUID = 615555755L

Parcelable的使用

parcelable的使用稍微复杂。但是有强大的as其实也很简单。再以Goods为例,多增加一个name属性。
先实现Parcelable接口,按照提示生成如下代码:

public class Goods implements Parcelable{
    private int mId;
    private String mName;

    public Goods(int id,String name){
        mId = id;
        mName = name;
    }

    protected Goods(Parcel in) {
        mId = in.readInt();
        mName = in.readString();
    }
    //自动生成的代码
    public static final Creator<Goods> CREATOR = new Creator<Goods>() {
        @Override
        public Goods createFromParcel(Parcel in) {
            return new Goods(in);
        }

        @Override
        public Goods[] newArray(int size) {
            return new Goods[size];
        }
    };

    public int getmId() {
        return mId;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mId);
        dest.writeString(mName);
    }
}

这样便实现了一个Parcel的序列化。当然这都是AS给你生成好的,我们来分析下里面的方法。
看多增加的一个构造器,参数为parcel,他给属性是通过Parcel.read()进行的,比如你的id为int类型,那么就为id = in.readInt(); 这部分应该很好理解。
再来看与之对应的wirteToParcel接口,就是把这些属性write出去。

在用intent传递数据的时候,可以传递实现序列化的类,当然list和map也可以,要求内部元素也是可序列化的。值得注意的是intent传递有个致命的缺陷,就是大小限制,详情请看: 江湖问题研究– intent传递有没有大小限制,是多少?

posted on 2016-03-04 11:33  木鱼哥  阅读(429)  评论(0编辑  收藏  举报

导航