一、android为什么要序列化?什么是序列化,怎么进行序列化
1.为什么要了解序列化?—— 进行Android开发的时候,无法将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
2.什么是序列化 —— 序列化,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
3.怎么通过序列化传输对象?
Android中Intent如果要传递类对象,可以通过两种方式实现。
方式一:Serializable,要传递的类实现Serializable接口传递对象,
方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
Serializable(Java自带):
Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
Parcelable(android 专用):
除了Serializable之外,使用Parcelable也可以实现相同的效果,
不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,
而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
实现Parcelable的作用
1)永久性保存对象,保存对象的字节序列到本地文件中;
2)通过序列化对象在网络中传递对象;
3)通过序列化在进程间传递对象。
选择序列化方法的原则
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable 。
应用场景
需要在多个部件(Activity或Service)之间通过Intent传递一些数据,简单类型(如:数字、字符串)的可以直接放入Intent。复杂类型必须实现Parcelable接口。
二、利用java自带的Serializable 进行序列化的例子
弄一个实体类 Person,利用Java自带的Serializable进行序列化
packagecom.amqr.serializabletest.entity;importjava.io.Serializable;/**
*/public class Person implements Serializable {private static final long serial VersionUID =7382351359868556980L;
private String name;
private int age;
public int getAge(){returnage; }
public void setAge(intage){this.age = age; }
public StringgetName(){returnname; }
public void setName(String name){this.name = name; }}
使用,MainActivity和SecondActivity结合使用
MainActivity
publicclassMainActivityextendsActivity{privateTextView mTvOpenNew;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){
Intent open =newIntent(MainActivity.this,SecondActivity.class);
Person person =newPerson();
person.setName("一去二三里");
person.setAge(18);
// 传输方式一,intent直接调用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 传输方式二,intent利用putExtras(注意s)传入bundle/**
Bundle bundle = new Bundle();
bundle.putSerializable("bundle_ser",person);
open.putExtras(bundle);
*/startActivity(open); } }); }}
* 进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,
* 我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
*
*
* Android中Intent如果要传递类对象,可以通过两种方式实现。
* 方式一:Serializable,要传递的类实现Serializable接口传递对象,
* 方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
*
* Serializable(Java自带):
* Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
*
* Parcelable(android 专用):
* 除了Serializable之外,使用Parcelable也可以实现相同的效果,
* 不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,
* 而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。
*/publicclassMainActivityextendsActivity{privateTextView mTvOpenNew;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){ Intent open =newIntent(MainActivity.this,SecondActivity.class); Person person =newPerson(); person.setName("一去二三里"); person.setAge(18);// 传输方式一,intent直接调用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 传输方式二,intent利用putExtras(注意s)传入bundle/**
Bundle bundle = new Bundle();
bundle.putSerializable("bundle_ser",person);
open.putExtras(bundle);
*/startActivity(open); } }); }}
SecondActivity
public class Second Activity extends Activity{privateTextView mTvDate;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTvDate = (TextView) findViewById(R.id.mTvDate);
Intent intent = getIntent();// 关键方法:getSerializableExtra ,我们的类是实现了Serializable接口的,所以写这个方法获得对象// public class Person implements SerializablePerson per = (Person)intent.getSerializableExtra("put_ser_test");//Person per = (Person)intent.getSerializableExtra("bundle_ser");mTvDate.setText("名字:"+per.getName()+"\\n"+"年龄:"+per.getAge()); }}
![](https://img.haomeiwen.com/i1083096/5c8668173c1c84e1.gif)
Serializable的序列化.gif
Serializable 到此完成
三、android专用的Parcelable的序列化的例子
我们写一个实体类,实现Parcelable接口,马上就被要求
1、复写describeContents方法和writeToParcel方法
2、实例化静态内部对象CREATOR,实现接口Parcelable.Creator 。
也就是,随便一个类实现了Parcelable接口就一开始就会变成这样子
Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
publicclassPenimplementsParcelable{privateString color;privateintsize;protectedPen(Parcel in){ color = in.readString(); size = in.readInt(); }publicstaticfinalCreator CREATOR =newCreator() {@OverridepublicPencreateFromParcel(Parcel in){returnnewPen(in); }@OverridepublicPen[] newArray(intsize) {returnnewPen[size]; } };@OverridepublicintdescribeContents(){return0; }@OverridepublicvoidwriteToParcel(Parcel dest,intflags){ dest.writeString(color); dest.writeInt(size); }}
系统已经帮我们做了很多事情,我们需要做的很简单,就写写我们自己需要的构造方法,写一下私有变量的get和set
大概变成这样子:
packagecom.amqr.serializabletest.entity;importandroid.os.Parcel;importandroid.os.Parcelable;/**
*/publicclassPenimplementsParcelable{privateString color;privateintsize;// 系统自动添加,给createFromParcel里面用protectedPen(Parcel in){ color = in.readString(); size = in.readInt(); }publicstaticfinalCreator CREATOR =newCreator() {/** * *@paramin *@return* createFromParcel()方法中我们要去读取刚才写出的name和age字段, * 并创建一个Person对象进行返回,其中color和size都是调用Parcel的readXxx()方法读取到的, * 注意这里读取的顺序一定要和刚才写出的顺序完全相同。 * 读取的工作我们利用一个构造函数帮我们完成了 */@OverridepublicPencreateFromParcel(Parcel in){returnnewPen(in);// 在构造函数里面完成了 读取 的工作}//供反序列化本类数组时调用的@OverridepublicPen[] newArray(intsize) {returnnewPen[size]; } };@OverridepublicintdescribeContents(){return0;// 内容接口描述,默认返回0即可。}@OverridepublicvoidwriteToParcel(Parcel dest,intflags){ dest.writeString(color);// 写出 colordest.writeInt(size);// 写出 size}// ======分割线,写写get和set//个人自己添加publicPen(){ }//个人自己添加publicPen(String color,intsize){this.color = color;this.size = size; }publicStringgetColor(){returncolor; }publicvoidsetColor(String color){this.color = color; }publicintgetSize(){returnsize; }publicvoidsetSize(intsize){this.size = size; }}
其实说起来Parcelable写起来也不是很麻烦,在as里面,我们的一个实体类写好私有变量之后,让这个类继承自Parcelable,接下的步骤是:
1、复写两个方法,分别是describeContents和writeToParcel
2、实例化静态内部对象CREATOR,实现接口Parcelable.Creator 。 以上这两步系统都已经帮我们自动做好了
3、自己写写我们所需要的构造方法,变量的get和set
实现自Parcelable实体Bean已经写好了,接下来我们结合MainActivity和ThirdActivity来使用以下:
* 进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,
* 我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
*
*
* Android中Intent如果要传递类对象,可以通过两种方式实现。
* 方式一:Serializable,要传递的类实现Serializable接口传递对象,
* 方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
*
* Serializable(Java自带):
* Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
*
* Parcelable(android 专用):
* 除了Serializable之外,使用Parcelable也可以实现相同的效果,
* 不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,
* 而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。
*/publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.mTvOpenNew).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){ Intent open =newIntent(MainActivity.this, SecondActivity.class); Person person =newPerson(); person.setName("一去二三里"); person.setAge(18);// 传输方式一,intent直接调用putExtra// public Intent putExtra(String name, Serializable value)open.putExtra("put_ser_test", person);// 传输方式二,intent利用putExtras(注意s)传入bundle/**
Bundle bundle = new Bundle();
bundle.putSerializable("bundle_ser",person);
open.putExtras(bundle);
*/startActivity(open); } });// 采用Parcelable的方式findViewById(R.id.mTvOpenThird).setOnClickListener(newView.OnClickListener() {@OverridepublicvoidonClick(View v){ Intent mTvOpenThird =newIntent(MainActivity.this,ThirdActivity.class); Pen tranPen =newPen(); tranPen.setColor("big red"); tranPen.setSize(98);// public Intent putExtra(String name, Parcelable value)mTvOpenThird.putExtra("parcel_test",tranPen); startActivity(mTvOpenThird); } }); }}
ThirdActivity
packagecom.amqr.serializabletest;importandroid.app.Activity;importandroid.os.Bundle;importandroid.widget.TextView;importcom.amqr.serializabletest.entity.Pen;/**
*/publicclassThirdActivityextendsActivity{privateTextView mTvThirdDate;@OverrideprotectedvoidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.activity_third); mTvThirdDate = (TextView) findViewById(R.id.mTvThirdDate);// Intent intent = getIntent();// Pen pen = (Pen)intent.getParcelableExtra("parcel_test");Pen pen = (Pen)getIntent().getParcelableExtra("parcel_test"); mTvThirdDate = (TextView) findViewById(R.id.mTvThirdDate); mTvThirdDate.setText("颜色:"+pen.getColor()+"\\n"+"大小:"+pen.getSize()); }}
![](https://img.haomeiwen.com/i1083096/598bf6a86b626d9f.gif)
Parcelable的方式.gif
完成,Serializable 和Parcelable 这两种方式都介绍完成了。接下说一说对比
四、Serializable 和Parcelable的对比
android上应该尽量采用Parcelable,效率至上
编码上:
Serializable代码量少,写起来方便
Parcelable代码多一些
效率上:
Parcelable的速度比高十倍以上
serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。
这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。
Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了
网友评论