您的位置:首页 > 移动开发 > Android开发

Android系统中Parcelable和Serializable的区别

2015-09-30 14:29 453 查看
进行Android开发的时候,我们都知道不能将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。

通过Android的API,我们知道有两种选择,即在传递对象时,需要对我们的对象进行 Parcelable 或者Serializable化。作为Java开发者,相信大家对Serializable
机制有一定了解,那为什么还需要 Parcelable呢?

为了回答这个问题,让我们分别来看看这两者的差异。


Serializable, 简单易用

123456789101112// access modifiers, accessors and constructors omitted for brevitypublic class SerializableDeveloper implements Serializable String name; int yearsOfExperience; List<Skill> skillSet; float favoriteFloat; static class Skill implements Serializable { String name; boolean programmingRelated; }}
serializable的迷人之处在于你只需要对某个类以及它的属性实现Serializable 接口即可。Serializable 接口是一种标识接口(marker interface),这意味着无需实现方法,Java便会对这个对象进行高效的序列化操作。这种方法的缺点是使用了反射,序列化的过程较慢。这种机制会在序列化的时候创建许多的临时对象,容易触发垃圾回收。

Parcelable, 速度至上

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

//
access modifiers, accessors and regular constructors ommited for brevity

class
ParcelableDeveloper
implements
Parcelable
{

String
name;

int
yearsOfExperience;

List<Skill>
skillSet;

float
favoriteFloat;

ParcelableDeveloper(Parcel
in)
{

this.name
=
in.readString();

this.yearsOfExperience
=
in.readInt();

this.skillSet
=
new
ArrayList<Skill>();

in.readTypedList(skillSet,
Skill.CREATOR);

this.favoriteFloat
=
in.readFloat();

}

void
writeToParcel(Parcel
dest,
int
flags)
{

dest.writeString(name);

dest.writeInt(yearsOfExperience);

dest.writeTypedList(skillSet);

dest.writeFloat(favoriteFloat);

}

int
describeContents()
{

return
0;

}

static
final
Parcelable.Creator<ParcelableDeveloper>
CREATOR

=
new
Parcelable.Creator<ParcelableDeveloper>()
{

ParcelableDeveloper
createFromParcel(Parcel
in)
{

return
new
ParcelableDeveloper(in);

}

ParcelableDeveloper[]
newArray(int
size)
{

return
new
ParcelableDeveloper[size];

}

};

static
class
Skill
implements
Parcelable
{

String
name;

boolean
programmingRelated;

Skill(Parcel
in)
{

this.name
=
in.readString();

 
18b82
; this.programmingRelated
=
(in.readInt()
==
1);

}

@Override

void
writeToParcel(Parcel
dest,
int
flags)
{

dest.writeString(name);

dest.writeInt(programmingRelated
?
1
:
0);

}

static
final
Parcelable.Creator<Skill>
CREATOR

=
new
Parcelable.Creator<Skill>()
{

Skill
createFromParcel(Parcel
in)
{

return
new
Skill(in);

}

Skill[]
newArray(int
size)
{

return
new
Skill[size];

}

};

@Override

int
describeContents()
{

return
0;

}

}

}

根据 google
工程师的说法,这些代码将会运行地特别快。原因之一就是我们已经清楚地知道了序列化的过程,而不需要使用反射来推断。同时为了更快地进行序列化,对象的代码也需要高度优化。

因此,很明显实现Parcelable并不容易。实现Parcelable接口需要写大量的模板代码,这使得对象代码变得难以阅读和维护。


速度测试

当然,我们还是想知道到底Parcelable相对于Serializable要快多少。


测试方法

通过将一个对象放到一个bundle里面然后调用Bundle#writeToParcel(Parcel,
int)方法来模拟传递对象给一个activity的过程,然后再把这个对象取出来。

在一个循环里面运行1000 次。

两种方法分别运行10次来减少内存整理,cpu被其他应用占用等情况的干扰。

参与测试的对象就是上面代码中的SerializableDeveloper 和 ParcelableDeveloper。

在多种Android软硬件环境上进行测试

LG Nexus 4 – Android 4.2.2

Samsung Nexus 10 – Android 4.2.2

HTC Desire Z – Android 2.3.3


结果





parcelable-vs-serializable

NEXUS 10


Serializable: 1.0004ms, Parcelable: 0.0850ms – 提升10.16倍。

NEXUS 4


Serializable: 1.8539ms – Parcelable: 0.1824ms – 提升11.80倍。

DESIRE Z


Serializable: 5.1224ms – Parcelable: 0.2938ms – 提升17.36倍。

由此可以得出: Parcelable 比 Serializable快了10多倍。有趣的是,即使在Nexus 10这样性能强悍的硬件上,一个相当简单的对象的序列化和反序列化的过程要花将近一毫秒。


总结

如果你想成为一个优秀的软件工程师,你需要多花点时间来实现 Parcelable ,因为这将会为你对象的序列化过程快10多倍,而且占用较少的资源。

但是大多数情况下, Serializable 的龟速不会太引人注目。你想偷点懒就用它吧,不过要记得serialization是一个比较耗资源的操作,尽量少使用。

如果你想要传递一个包含许多对象的列表,那么整个序列化的过程的时间开销可能会超过一秒,这会让屏幕转向的时候变得很卡顿。

本文翻译自:http://www.developerphil.com/parcelable-vs-serializable/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android android开发