一、Android为什么要序列化?什么是序列化,怎么进行序列化

why

为什么要了解序列化?—— 进行Android开发的时候,无法将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。

what

什么是序列化 —— 序列化,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。

how

怎么通过序列化传输对象?

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进行序列化

package com.amqr.serializabletest.entity;
import java.io.Serializable;
/**
* User: LJM
* Date&Time: 2016-02-22 & 14:16
* Describe: Describe Text
*/
public class Person implements Serializable{
private static final long serialVersionUID = 7382351359868556980L;
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

使用,MainActivity和SecondActivity结合使用

MainActivity

package com.amqr.serializabletest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.amqr.serializabletest.entity.Person;
/**
* 进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,
* 我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
*
*
* Android中Intent如果要传递类对象,可以通过两种方式实现。
* 方式一:Serializable,要传递的类实现Serializable接口传递对象,
* 方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
*
* Serializable(Java自带):
* Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
*
* Parcelable(android 专用):
* 除了Serializable之外,使用Parcelable也可以实现相同的效果,
* 不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,
* 而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。
*/
public class MainActivity extends Activity {
private TextView mTvOpenNew;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.mTvOpenNew).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent open = new Intent(MainActivity.this,SecondActivity.class);
Person person = new Person();
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

package com.amqr.serializabletest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
import com.amqr.serializabletest.entity.Person;
/**
* User: LJM
* Date&Time: 2016-02-22 & 11:56
* Describe: Describe Text
*/
public class SecondActivity extends Activity{
private TextView mTvDate;
@Override
protected void onCreate(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 Serializable
Person per = (Person)intent.getSerializableExtra("put_ser_test");
//Person per = (Person)intent.getSerializableExtra("bundle_ser");
mTvDate.setText("名字:"+per.getName()+"\n"
+"年龄:"+per.getAge());
}
}

Serializable的序列化.gif

Serializable 到此完成

三、android专用的Parcelable的序列化的例子

我们写一个实体类,实现Parcelable接口,马上就被要求

1、复写describeContents方法和writeToParcel方法

2、实例化静态内部对象CREATOR,实现接口Parcelable.Creator 。

也就是,随便一个类实现了Parcelable接口就一开始就会变成这样子

Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。

public class Pen implements Parcelable{
private String color;
private int size;
protected Pen(Parcel in) {
color = in.readString();
size = in.readInt();
}
public static final Creator<Pen> CREATOR = new Creator<Pen>() {
@Override
public Pen createFromParcel(Parcel in) {
return new Pen(in);
}
@Override
public Pen[] newArray(int size) {
return new Pen[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(color);
dest.writeInt(size);
}
}

系统已经帮我们做了很多事情,我们需要做的很简单,就写写我们自己需要的构造方法,写一下私有变量的get和set

大概变成这样子:

package com.amqr.serializabletest.entity;
import android.os.Parcel;
import android.os.Parcelable;
/**
* User: LJM
* Date&Time: 2016-02-22 & 14:52
* Describe: Describe Text
*/
public class Pen implements Parcelable{
private String color;
private int size; // 系统自动添加,给createFromParcel里面用
protected Pen(Parcel in) {
color = in.readString();
size = in.readInt();
}
public static final Creator<Pen> CREATOR = new Creator<Pen>() {
/**
*
* @param in
* @return
* createFromParcel()方法中我们要去读取刚才写出的name和age字段,
* 并创建一个Person对象进行返回,其中color和size都是调用Parcel的readXxx()方法读取到的,
* 注意这里读取的顺序一定要和刚才写出的顺序完全相同。
* 读取的工作我们利用一个构造函数帮我们完成了
*/
@Override
public Pen createFromParcel(Parcel in) {
return new Pen(in); // 在构造函数里面完成了 读取 的工作
}
//供反序列化本类数组时调用的
@Override
public Pen[] newArray(int size) {
return new Pen[size];
}
}; @Override
public int describeContents() {
return 0; // 内容接口描述,默认返回0即可。
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(color); // 写出 color
dest.writeInt(size); // 写出 size
}
// ======分割线,写写get和set
//个人自己添加
public Pen() {
}
//个人自己添加
public Pen(String color, int size) {
this.color = color;
this.size = size;
} public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}

其实说起来Parcelable写起来也不是很麻烦,在as里面,我们的一个实体类写好私有变量之后,让这个类继承自Parcelable,接下的步骤是:

1、复写两个方法,分别是describeContents和writeToParcel

2、实例化静态内部对象CREATOR,实现接口Parcelable.Creator 。 以上这两步系统都已经帮我们自动做好了

3、自己写写我们所需要的构造方法,变量的get和set

实现自Parcelable实体Bean已经写好了,接下来我们结合MainActivity和ThirdActivity来使用以下:

MainActivity

package com.amqr.serializabletest;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import com.amqr.serializabletest.entity.Pen;
import com.amqr.serializabletest.entity.Person;
/**
* 进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,
* 我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。
*
*
* Android中Intent如果要传递类对象,可以通过两种方式实现。
* 方式一:Serializable,要传递的类实现Serializable接口传递对象,
* 方式二:Parcelable,要传递的类实现Parcelable接口传递对象。
*
* Serializable(Java自带):
* Serializable是序列化的意思,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。
*
* Parcelable(android 专用):
* 除了Serializable之外,使用Parcelable也可以实现相同的效果,
* 不过不同于将对象进行序列化,Parcelable方式的实现原理是将一个完整的对象进行分解,
* 而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了。
要求被传递的对象必须实现上述2种接口中的一种才能通过Intent直接传递。
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.mTvOpenNew).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent open = new Intent(MainActivity.this, SecondActivity.class);
Person person = new Person();
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(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent mTvOpenThird = new Intent(MainActivity.this,ThirdActivity.class);
Pen tranPen = new Pen();
tranPen.setColor("big red");
tranPen.setSize(98);
// public Intent putExtra(String name, Parcelable value)
mTvOpenThird.putExtra("parcel_test",tranPen);
startActivity(mTvOpenThird);
}
});
}
}

ThirdActivity

package com.amqr.serializabletest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import com.amqr.serializabletest.entity.Pen;
/**
* User: LJM
* Date&Time: 2016-02-22 & 14:47
* Describe: Describe Text
*/
public class ThirdActivity extends Activity{
private TextView mTvThirdDate;
@Override
protected void onCreate(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());
}
}

Parcelable的方式.gif

完成,Serializable 和Parcelable 这两种方式都介绍完成了。接下说一说对比

四、Serializable 和Parcelable的对比

android上应该尽量采用Parcelable,效率至上

编码上:

Parcelable代码量少,写起来方便

Parcelable代码多一些

效率上:

Parcelable的速度比高十倍以上

serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。

这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。

Parcelable方式的实现原理是将一个完整的对象进行分解,而分解后的每一部分都是Intent所支持的数据类型,这样也就实现传递对象的功能了

五、demo

http://pan.baidu.com/s/1dDLGWKD

参考

Android中Parcelable接口用法
http://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html

Android系统中Parcelable和Serializable的区别
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0204/2410.html

Parcelable和Serializable的区别的更多相关文章

  1. Android系统中Parcelable和Serializable的区别,自动化实现Parcelable接口的插件

    Parcelable和Serializable的区别 参考地址:http://greenrobot.me/devpost/android-parcelable-serializable/ 由于最终的区 ...

  2. Android Parcelable和Serializable的区别,androidparcelable

    本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...

  3. Android Parcelable和Serializable的区别

    本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...

  4. [转]Android Parcelable和Serializable的区别

    本文主要介绍Parcelable和Serializable的作用.效率.区别及选择,关于Serializable的介绍见Java 序列化的高级认识. 1.作用 Serializable的作用是为了保存 ...

  5. Android系统中Parcelable和Serializable的区别

    转载:https://greenrobot.me/devpost/android-parcelable-serializable/ 进行Android开发的时候,我们都知道不能将对象的引用传给Acti ...

  6. 【安卓开发】Android系统中Parcelable和Serializable的区别

    http://greenrobot.me/devpost/android-parcelable-serializable/ 进行Android开发的时候,我们都知道不能将对象的引用传给Activiti ...

  7. android Activity之间数据传递 Parcelable和Serializable接口的使用

    Activity之间传数据时,为了避免麻烦,往往会将一些值封装成对象,然后将整个对象传递过去.传对象的时候有两种情况,一种是实现Parcelable接口,一种是实现Serializable接口.0.解 ...

  8. Android中Parcelable和Serializable接口用法

    1. Parcelable接口 Interface for classes whose instances can be written to and restored from a Parcel. ...

  9. Android中Parcelable与Serializable接口用法

    转自: Android中Parcelable接口用法 1. Parcelable接口 Interface for classes whose instances can be written to a ...

随机推荐

  1. poj3341

    AC自动机,用40^4 * 50 * 10的空间进行dp. 最大的难点在于hash. hash一个数列f,数列中的每一位都有一个上限g,即f[i]<=g[i]. 那么可以将该数列hash为这样一 ...

  2. bootstrap 重写JS的alert、comfirm函数

    原理是使用bootstrap的Modal插件实现. 一.在前端模板合适的地方,加入Modal展现div元素. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ...

  3. jquery的基本事件大全

    ].name); });jQuery.getScript( url, [callback] ) 使用GET请求javascript文件并执行. $.getScript(”test.js”, funct ...

  4. 【编程题目】一串首尾相连的珠子(m 个),有 N 种颜色(N<=10),取出其中一段,要求包含所有 N 中颜色,并使长度最短。

    40.百度研发笔试题 2)一串首尾相连的珠子(m 个),有 N 种颜色(N<=10),设计一个算法,取出其中一段,要求包含所有 N 中颜色,并使长度最短.并分析时间复杂度与空间复杂度. 思路: ...

  5. 【el表达式】jsp中设置默认图像

    <img alt="头像" src="${empty members.headPic ?'images/icon.png':members.headPic}&quo ...

  6. ios手势

    iOS 手势操作:拖动.捏合.旋转.点按.长按.轻扫.自定义 大 中 小   1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. i ...

  7. mongodb 3.2 用户权限管理配置

    使用mongodb 有段时间了,由于是在内网使用,便没有设置权限,一直是裸奔. 最近有时间,研究了下mongodb 3.2 的用户权限配置,网上有许多用户权限配置的文章,不过大多是之前版本,有些出入, ...

  8. chrome进入控制台时自动进入断点模式的解决方法

    简单粗暴,不知道为什么,去掉那个√就好了

  9. 树形DP习题

    听闻noip要考树形DP,本蒟蒻万分惶恐,特刷一坨题目,以慰受惊之心. codevs 1486 /*和非常出名的"选课"是一个题*/ #include<cstdio> ...

  10. MVC4 @RenderBody、@RenderSection、@RenderPage、Html.RenderPartial、Html.RenderAction的作用和区别

    1. RenderBody在Razor引擎中没有了“母版页”,取而代之的是叫做“布局”的页面(_Layout.cshtml)放在了共享视图文件夹中.在这个页面中,会看到标签里有这样一条语句:@Rend ...