Android序列化parcelable和 serializable分析
2016-07-03 16:51
615 查看
Android中难免使用Intent在各个组件间进行传递数据,这个时候如果需要传递对象,就需要对对象进行序列化,序列化的方式有两种一种是parcelable,位于android.os包下,而serializable则位于java.io包下,下面分别对这两种方式进行一下分析。
一、通过parcelable方法实现序列化
notification.java 代码如下
从代码中可以看出想完成序列化的工作有几点需要注意的。
1、必须实现parcelable接口,然后复写两个方法,一个是describeContents方法一个是writeToParcel方法,但是第一个describeContents方法我们基本上不用去理会他,关心的内容放在writeToParcel上。
2、特别需要注意的是除了复写两个方法后还需要新建一个静态的Parcelable.Creator类,这里需要注意的是类名必须是CREATOR,否则将会收到错误警告如图所示
3、最核心的操作就是对数据进行序列化只要通过两个方法来实现
通过这两个方法完成对数据的序列化操作,但是这里需要注意的是如果使用基本数据类型可以使用writeInt,writeLong,writeDobule等等方法,如果其中嵌套对象呢,看下面的Message.java代码
代码中可以看出第一个message中嵌套一个实现了parcelable接口的类,上面我们提到了如果都是基本数据类型进行序列化,但是现在不是基本数据类型了我们如何序列化呢,想必在上面的message.java代码中已经看到了需要使用source.readParcelable(Notification.class.getClassLoader());通过readParcelable方法,这里需要注意的是参数需要一个classLoader,千万不要传入null,否则序列化的时候会抛出异常。
既然有readParcelable那我们就需要对应的writeParcelable,通过这两个方法基本完成了对于实现parcelable对象嵌套的序列化。
3、对于嵌套map的序列化操作,上面我们提到了基本数据类型和对象的嵌套序列化,但是如果我现在用在类中嵌套一个map呢这个时候该如何序列化。答案还是在message.java中,我们通过下面方法实现
这里面我提供了两种方式进行map的序列化操作,其中一种我们可以通过writeMap和readMap方法实现,这种方法和上面对象的序列化类似也是需要个classloader,这个classloader你可以通过你的map.class.getClassLoader来获取。第二种就是通过上图中注释掉的部分来是实现,通过循环遍历将里面的key和value分别序列化,这种方式也同样能实现对map的序列化操作。(注:当使用map序列化的时候我发现一个问题,就是对于map成员变量必须进行初始化也就是必须进行messaage.java中的 private
ArrayMap<String, String> data = new ArrayMap<>();如果不初始化将会抛出异常,如下图所示)
嵌套类的时候不需要初始化,map需要初始化,这一点我比较疑惑,如果是我姿势不对还请大家指点一二。
二、通过serializable方法实现序列化
这种方法比较容易实现,如下图所示
只需要通过实现serializable接口就可以了,如果里面还要嵌套类,只要将所有的类实现serializable接口就好了。
总结:通过上面的分析我们可以看出serializable使用简单,而parcelable稍微复杂一点,但是serializable的兼容性更好点,原因就是parcelable是android.os包下的,由于android系统版本差异,可能会有一些不同,但是在内容开销方面要比serializable少很多,所以效率和性能上会高于serializable,所以两种方式各有利弊选择使用哪个看自己的实际需求。
能想到的暂时就是这么多,希望有说的不对的地方大家指出来,大家一同进步,非常感谢。最后附上源码,方便大家查看。
http://download.csdn.net/detail/mahaiming1990/9566324
一、通过parcelable方法实现序列化
notification.java 代码如下
public class Notification implements Parcelable { private String title; private String body; private String icon; private String sound; private String tag; private String color; private String clickAction; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getSound() { return sound; } public void setSound(String sound) { this.sound = sound; } public String getTag() { return tag; } public void setTag(String tag) { this.tag = tag; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public String getClickAction() { return clickAction; } public void setClickAction(String clickAction) { this.clickAction = clickAction; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(title); dest.writeString(body); dest.writeString(icon); dest.writeString(sound); dest.writeString(tag); dest.writeString(color); dest.writeString(clickAction); } static Parcelable.Creator CREATOR = new Parcelable.Creator() { @Override public Notification createFromParcel(Parcel source) { return new Notification(source); } @Override public Notification[] newArray(int size) { return new Notification[size]; } }; private Notification(Parcel source) { title = source.readString(); body = source.readString(); ; icon = source.readString(); ; color = source.readString(); ; tag = source.readString(); ; clickAction = source.readString(); ; sound = source.readString(); } public Notification() { } }
从代码中可以看出想完成序列化的工作有几点需要注意的。
1、必须实现parcelable接口,然后复写两个方法,一个是describeContents方法一个是writeToParcel方法,但是第一个describeContents方法我们基本上不用去理会他,关心的内容放在writeToParcel上。
2、特别需要注意的是除了复写两个方法后还需要新建一个静态的Parcelable.Creator类,这里需要注意的是类名必须是CREATOR,否则将会收到错误警告如图所示
3、最核心的操作就是对数据进行序列化只要通过两个方法来实现
通过这两个方法完成对数据的序列化操作,但是这里需要注意的是如果使用基本数据类型可以使用writeInt,writeLong,writeDobule等等方法,如果其中嵌套对象呢,看下面的Message.java代码
public class Message implements Parcelable { private String to; private String from; private ArrayMap data = new ArrayMap<>(); private String messageType; private String messageId; private long sendTime; private Notification notification; public String getMessageType() { return messageType; } public void setMessageType(String messageType) { this.messageType = messageType; } public String getMessageId() { return messageId; } public void setMessageId(String messageId) { this.messageId = messageId; } public long getSendTime() { return sendTime; } public void setSendTime(long sendTime) { this.sendTime = sendTime; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public ArrayMap getData() { return data; } public void setData(ArrayMap data) { this.data = data; } public Notification getNotification() { return notification; } public void setNotification(Notification notification) { this.notification = notification; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(to); dest.writeString(from); dest.writeParcelable(notification, flags); dest.writeLong(sendTime); // dest.writeInt(data.size()); // for (Map.Entry entry : data.entrySet()) { // dest.writeString(entry.getKey()); // dest.writeString(entry.getValue()); // } dest.writeMap(data); } static Creator CREATOR = new Creator() { @Override public Message createFromParcel(Parcel source) { return new Message(source); } @Override public Message[] newArray(int size) { return new Message[size]; } }; private Message(Parcel source) { to = source.readString(); from = source.readString(); notification = source.readParcelable(Notification.class.getClassLoader()); sendTime = source.readLong(); // int size = source.readInt(); // for (int i = 0; i < size; i++) { // String key = source.readString(); // String value = source.readString(); // data.put(key, value); // } source.readMap(data, ArrayMap.class.getClassLoader()); } public Message() { } }
代码中可以看出第一个message中嵌套一个实现了parcelable接口的类,上面我们提到了如果都是基本数据类型进行序列化,但是现在不是基本数据类型了我们如何序列化呢,想必在上面的message.java代码中已经看到了需要使用source.readParcelable(Notification.class.getClassLoader());通过readParcelable方法,这里需要注意的是参数需要一个classLoader,千万不要传入null,否则序列化的时候会抛出异常。
既然有readParcelable那我们就需要对应的writeParcelable,通过这两个方法基本完成了对于实现parcelable对象嵌套的序列化。
3、对于嵌套map的序列化操作,上面我们提到了基本数据类型和对象的嵌套序列化,但是如果我现在用在类中嵌套一个map呢这个时候该如何序列化。答案还是在message.java中,我们通过下面方法实现
这里面我提供了两种方式进行map的序列化操作,其中一种我们可以通过writeMap和readMap方法实现,这种方法和上面对象的序列化类似也是需要个classloader,这个classloader你可以通过你的map.class.getClassLoader来获取。第二种就是通过上图中注释掉的部分来是实现,通过循环遍历将里面的key和value分别序列化,这种方式也同样能实现对map的序列化操作。(注:当使用map序列化的时候我发现一个问题,就是对于map成员变量必须进行初始化也就是必须进行messaage.java中的 private
ArrayMap<String, String> data = new ArrayMap<>();如果不初始化将会抛出异常,如下图所示)
嵌套类的时候不需要初始化,map需要初始化,这一点我比较疑惑,如果是我姿势不对还请大家指点一二。
二、通过serializable方法实现序列化
这种方法比较容易实现,如下图所示
只需要通过实现serializable接口就可以了,如果里面还要嵌套类,只要将所有的类实现serializable接口就好了。
总结:通过上面的分析我们可以看出serializable使用简单,而parcelable稍微复杂一点,但是serializable的兼容性更好点,原因就是parcelable是android.os包下的,由于android系统版本差异,可能会有一些不同,但是在内容开销方面要比serializable少很多,所以效率和性能上会高于serializable,所以两种方式各有利弊选择使用哪个看自己的实际需求。
能想到的暂时就是这么多,希望有说的不对的地方大家指出来,大家一同进步,非常感谢。最后附上源码,方便大家查看。
http://download.csdn.net/detail/mahaiming1990/9566324
相关文章推荐
- Android之史上最全最简单最有用的第三方开源库收集整理
- 谈Android中Activity的学习和收获
- Android四大组件之Activity(中)
- Android开发工程目录结构简介
- Android: Drawable Resources
- [译]Android内存泄漏的八种可能
- android学习日记之activity
- android 检测sqlite数据表中某字段(列)是否存在
- Android常见异常
- Android Studio2.1.2导入jar包和so文件方法
- Android新浪微博开发(三)完结篇之调用新浪微博API实现信息展示
- Android中如何解决Thread is already started问题
- 转: 将Eclipse代码导入到AndroidStudio的两种方式
- Android -- 设置textview文字居中或者控件居中
- android studio __android_log_print 问题
- 《Android开发艺术探索》读书笔记 (15) Android性能优化
- Android四大组件之 Activity(上)
- GeekBand第八周笔记
- 浅谈Android多屏幕的事
- Android中编辑打电话