Android序列化——Serializable与Parcelable
2016-01-03 21:33
621 查看
序列化这个名词,我们在学习java的时候早有耳闻,与之相对的还有反序列化。
在java中我们印象中常用的序列化方式是实现Serializable接口。
那么,在android中,我们如何实现这样的序列化和反序列化呢?
序列化:将对象转为字节序列的过程,我们称之为序列化。
序列化的意义:序列化主要是为了解决对象的持久化以及对象在进程间的传递、网络传输等。
(1)持久化:当你在一个程序中,声明一个类的后,程序关闭,那么这个类也肯定是被内存释放了。如果你想要在程序关闭后,这个类内容仍然能存在,那么你就需要对它做持久化操作。常用的方法是:用对象处理流(ObjectOutputStream)来把这个类对象存储在本地(这个过程,就是序列化-持久化过程)。当你想使用这个已经被序列化-持久化的类对象时,用对象处理流(ObjectInputStream)取得类对象数据,加载到程序中。
(2)进程间对象传递:比如,两个操作系统之间的两个进程A与B,因为不公用内存。你如果想要从A传递一个类对象到B,那么,你需要把A的类对象字节化,在B中接收字节并处理。字节是两个系统都认可并能处理的方式。
以下两种,就是Android中涉及到的序列化接口。
(1)Serializable
如果你想要使用这个序列化方式。那你首先要实现这个接口,这个Serializable接口只是一个标志,并不需要实现它的类做额外的操作。
当实现这个接口后,Android(java)系统会自动完成这个接口的序列化。
(2)Parcelable
如果你想要使用这个序列化方式。那你首先也是实现这个接口。与Serializable相比,这个接口,需要你实现几个必要的接口方法。并在方法中写入代码。
具体的代码:
(1)序列化接口实现
(2)序列化接口实现类的传递
我们在android中加入如下代码,用于界面的跳转(从mainactivity.java跳转到otheractivity.java):
(3)序列化接口实现类的接收和解析
现在让我们看看,在OtherActivity.java中,我们是如何接收并解析的。
从上面的写法,我们看出,这是一种很简便的写法。那么Parcelable的接口实现是怎么样的呢?
(1)Parcelable接口的实现
你会发现,Parcelable的写法比起Serializable的写法复杂了。它要实现两个必要的方法和一个接口。
必要实现方法:writeToParcel、describeContents。分别代表写入数据到Parcel以及内容描述。writeToParcel我们可以理解为流写入Parcel、describeContents方法一般默认返回0即可。
必要实现接口:public final static Parcelable.Creator<ParcelableClass> CREATOR。这是个很特别的接口,按约定,这个接口的名字你还不能更改,只能是CREATOR,并且前面的修饰需要时public final static。
CREATOR接口的实现中,有两个方法,createFromParcel(可以看成是从Parcel中获取流,与上方的writeToParcel相对应),newArray(返回多个类对象)。
(2)Parcelable接口实现类的传递
(3)Parcelable接口实现类的接收与解析
对比,这两个接口实现类的使用。你轻易发现,Serializable的使用更方便,Parcelable的使用比较麻烦。那我们如何选择使用哪个序列化方法呢?
一般情况下,持久化我们选择使用Serializable接口。这里有一个序列化和反序列化过程。
序列化:
以下就是一个持久化过程,将类对象持久化到obj中。
反序列化:
以下就是一个从obj中读取类对象数据的过程,就是反序列化。
以上主要是对序列化的一些简要归纳。
在java中我们印象中常用的序列化方式是实现Serializable接口。
那么,在android中,我们如何实现这样的序列化和反序列化呢?
序列化的意义
序列化,我们首先要明白它代表的含义以及为什么要使用序列化。序列化:将对象转为字节序列的过程,我们称之为序列化。
序列化的意义:序列化主要是为了解决对象的持久化以及对象在进程间的传递、网络传输等。
(1)持久化:当你在一个程序中,声明一个类的后,程序关闭,那么这个类也肯定是被内存释放了。如果你想要在程序关闭后,这个类内容仍然能存在,那么你就需要对它做持久化操作。常用的方法是:用对象处理流(ObjectOutputStream)来把这个类对象存储在本地(这个过程,就是序列化-持久化过程)。当你想使用这个已经被序列化-持久化的类对象时,用对象处理流(ObjectInputStream)取得类对象数据,加载到程序中。
(2)进程间对象传递:比如,两个操作系统之间的两个进程A与B,因为不公用内存。你如果想要从A传递一个类对象到B,那么,你需要把A的类对象字节化,在B中接收字节并处理。字节是两个系统都认可并能处理的方式。
序列化的方式
Android中序列化有哪些方式?以下两种,就是Android中涉及到的序列化接口。
(1)Serializable
如果你想要使用这个序列化方式。那你首先要实现这个接口,这个Serializable接口只是一个标志,并不需要实现它的类做额外的操作。
当实现这个接口后,Android(java)系统会自动完成这个接口的序列化。
(2)Parcelable
如果你想要使用这个序列化方式。那你首先也是实现这个接口。与Serializable相比,这个接口,需要你实现几个必要的接口方法。并在方法中写入代码。
序列化的使用——数据传输
对于上面我们介绍的两种序列化方式,我们分别也做演示,看看在Android中如何使用。Serializable的使用
它的使用,在android中是很简单的:实现序列化接口,传递实现序列化接口的类对象,解析传递过来的序列化类对象。具体的代码:
(1)序列化接口实现
package com.example.serializ_csdn; import java.io.Serializable; public class SerializableClass implements Serializable{ /** * UID,默认有两种方式。如果不限制使用,可直接使用以下1L方式 * 如果对序列化验证严格,可用另一种方式,生成一长串long数据。 */ private static final long serialVersionUID = 1L; /** * 以下是类的元素 */ private String name; private int age; private boolean isMan; /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public int getAge() { return age; } /** * @param age the age to set */ public void setAge(int age) { this.age = age; } /** * @return the isMan */ public boolean isMan() { return isMan; } /** * @param isMan the isMan to set */ public void setMan(boolean isMan) { this.isMan = isMan; } }这个类定义的很简单。类中的属性元素有三项,名字、年龄、是否男。
(2)序列化接口实现类的传递
我们在android中加入如下代码,用于界面的跳转(从mainactivity.java跳转到otheractivity.java):
SerializableClass sClass=new SerializableClass(); sClass.setName("赵云"); sClass.setAge(18); sClass.setMan(true); Intent intent=new Intent(); intent.setClass(MainActivity.this, OtherActivity.class); intent.putExtra("tag", 1); intent.putExtra("s_data", sClass); startActivity(intent);这里我们看到,类对象做了组装,并且用“s_data”作为标识,传递这个类对象到OtherActivity中。
(3)序列化接口实现类的接收和解析
现在让我们看看,在OtherActivity.java中,我们是如何接收并解析的。
SerializableClass sClass=(SerializableClass)this.getIntent().getSerializableExtra("s_data");上面这句代码,就完成了它的序列化解析。它包含了反序列化的过程。
从上面的写法,我们看出,这是一种很简便的写法。那么Parcelable的接口实现是怎么样的呢?
Parcelable的使用
Parcelable的接口实现,我们也用代码来说明。我们用同样的类属性:名字、年龄、是否男。(1)Parcelable接口的实现
package com.example.serializ_csdn; import android.os.Parcel; import android.os.Parcelable; public class ParcelableClass implements Parcelable{ private String name; private int age; private boolean isMan; /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the age */ public int getAge() { return age; } /** * @param age the age to set */ public void setAge(int age) { this.age = age; } /** * @return the isMan */ public boolean isMan() { return isMan; } /** * @param isMan the isMan to set */ public void setMan(boolean isMan) { this.isMan = isMan; } @Override public int describeContents() { // TODO Auto-generated method stub return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // TODO Auto-generated method stub dest.writeString(name); dest.writeInt(age); dest.writeInt(isMan?1:0); } public final static Parcelable.Creator<ParcelableClass> CREATOR =new Parcelable.Creator<ParcelableClass>() { @Override public ParcelableClass createFromParcel(Parcel source) { // TODO Auto-generated method stub ParcelableClass pClass=new ParcelableClass(); pClass.name=source.readString(); pClass.age=source.readInt(); pClass.isMan=(source.readInt()==1)?true:false; return pClass; } @Override public ParcelableClass[] newArray(int size) { // TODO Auto-generated method stub return new ParcelableClass[size]; } }; }
你会发现,Parcelable的写法比起Serializable的写法复杂了。它要实现两个必要的方法和一个接口。
必要实现方法:writeToParcel、describeContents。分别代表写入数据到Parcel以及内容描述。writeToParcel我们可以理解为流写入Parcel、describeContents方法一般默认返回0即可。
必要实现接口:public final static Parcelable.Creator<ParcelableClass> CREATOR。这是个很特别的接口,按约定,这个接口的名字你还不能更改,只能是CREATOR,并且前面的修饰需要时public final static。
CREATOR接口的实现中,有两个方法,createFromParcel(可以看成是从Parcel中获取流,与上方的writeToParcel相对应),newArray(返回多个类对象)。
(2)Parcelable接口实现类的传递
ParcelableClass pClass=new ParcelableClass(); pClass.setName("关羽"); pClass.setAge(20); pClass.setMan(true); Intent intent2=new Intent(); intent2.setClass(this, OtherActivity.class); intent2.putExtra("tag", 2); intent2.putExtra("p_data", pClass); startActivity(intent2);
(3)Parcelable接口实现类的接收与解析
ParcelableClass pClass=(ParcelableClass)this.getIntent().getParcelableExtra("p_data");
对比,这两个接口实现类的使用。你轻易发现,Serializable的使用更方便,Parcelable的使用比较麻烦。那我们如何选择使用哪个序列化方法呢?
序列化的使用——持久化
上面我们讲的主要是序列化接口在数据传递过程中的使用,那么在序列化的持久化,我们怎么用代表描述呢?一般情况下,持久化我们选择使用Serializable接口。这里有一个序列化和反序列化过程。
序列化:
以下就是一个持久化过程,将类对象持久化到obj中。
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("obj")); out.writeObject(new SerializableClass()); out.flush(); out.close();
反序列化:
以下就是一个从obj中读取类对象数据的过程,就是反序列化。
ObjectInputStream in=new ObjectInputStream(new FileInputStream("obj")); in.readObject(); in.close();
序列化接口的选择
Parcelable的性能比Serializable好,在内存开销方面较小,所以在内存间数据传输时推荐使用Parcelable,如activity间传输数据,而Serializable可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable,因为android不同版本Parcelable可能不同,所以不推荐使用Parcelable进行数据持久化。以上主要是对序列化的一些简要归纳。
源码
演示源码地址:Android序列化——Serializable与Parcelable相关文章推荐
- C#自定义序列化ISerializable的实现方法
- c#数据的序列化和反序列化(推荐版)
- c#序列化详解示例
- c#对象反序列化与对象序列化示例详解
- .net实现序列化与反序列化实例解析
- C#实现复杂XML的序列化与反序列化
- C#中Serializable序列化实例详解
- asp.net类序列化生成xml文件实例详解
- C#实现的json序列化和反序列化代码实例
- C#序列化与反序列化(Serialize,Deserialize)实例详解
- C#二进制序列化实例分析
- asp.net 序列化and反序列化演示
- Json序列化和反序列化方法解析
- 解析PHP多种序列化与反序列化的方法
- 深入理解Java对象的序列化与反序列化的应用
- WebLogic 10.3.6.0 升级反序列化漏洞补丁
- Hadoop序列化&Java序列化
- Android Parcelable接口
- Android Intent传值 Serializable Parcelable
- Android开发,在Activity中切换不同的Fragment