概念
序列化
将数据结构或对象转化成二进制串的过程
反序列化
将再序列化过程中所生成的二进制串转换成数据结构或对象的过程
面试题
serialVersionUID的做用
serialVersionUID
用来表明类的不同版本间的兼容性。如果你修改了此类
, 要修改此值。否则以前用老版本的类序列化的类恢复时会报错
: InvalidClassException。
不指定 serialVersionUID的后果是,当你添加或修改类中的任何字段时, 则已序列化类将无法恢复, 因为为新类和旧序列化对象生成的 serialVersionUID 将有所不同。
Android里面为什么要设计出Bundle而不是直接用Map结构
Bundle
内部是由
ArrayMap
实现的,
ArrayMap
的内部实现是两个数组,一个
int
数组是存储对象数
据对应下标,一个对象数组保存
key
和
value
,内部使用二分法对
key
进行排序,所以在添加、删
除、查找数据的时候,都会使用二分法查找,只适合于小数据量操作,如果在数据量比较大的情况
下,那么它的性能将退化。而
HashMap
内部则是数组
+链表结构,所以在数据量较少的时候,
HashMap
的
Entry Array
比
ArrayMap
占用更多的内存。因为使用
Bundle
的场景大多数为小数据
量,我没见过在两个
Activity
之间传递
10
个以上数据的场景,所以相比之下,在这种情况下使用
ArrayMap
保存数据,在操作速度和内存占用上都具有优势,因此使用
Bundle
来传递数据,可以保
证更快的速度和更少的内存占用。
另外一个原因,则是在
Android
中如果使用
Intent
来携带数据的话,需要数据是基本类型或者是可
序列化类型,
HashMap
使用
Serializable
进行序列化,而
Bundle
则是使用
Parcelable
进行序列化。
而在
Android
平台中,更推荐使用
Parcelable
实现序列化,虽然写法复杂,但是开销更小,所以为
了更加快速的进行数据的序列化和反序列化,系统封装了
Bundle
类,方便我们进行数据的传输。
Android中Intent/Bundle的通信原理及大小限制
Intent
中的
Bundle
是使用
Binder
机制进行数据传送的。能使用的
Binder
的缓冲区是有大小限
制的(有些手机是
2 M
),而一个进程默认有
16
个
Binder
线程,所以一个线程能占用的缓冲区
就更小了( 有人以前做过测试,大约一个线程可以占用
128 KB
)。所以当你看到
The Binder
transaction failed because it was too large
这类
TransactionTooLargeException
异常时,你应
该知道怎么解决了
为何Intent不能直接在组件间传递对象而要通过序列化机制?
Intent
在启动其他组件时,会离开当前应用程序进程,进入
ActivityManagerService
进程
(
intent.prepareToLeaveProcess()
),这也就意味着,
Intent
所携带的数据要能够在不同进程间
传输。首先我们知道,
Android
是基于
Linux
系统,不同进程之间的
java
对象是无法传输,所以我
们此处要对对象进行序列化,从而实现对象在 应用程序进程 和
ActivityManagerService
进程 之间
传输。
而
Parcel
或者
Serializable
都可以将对象序列化,其中,
Serializable
使用方便,但性能不如
Parcel
容器,后者也是
Android
系统专门推出的用于进程间通信等的接口