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传递有没有大小限制,是多少?