前言:Activity就是Android世界的controller,它们构成了Android App里面的每一个页面,当然我们还会使用Fragment来将页面进一步划分,通过Fragment可以对特定业务模块的View+逻辑封装,让其与Activity解耦,同时还可以有自己的生命周期,让我们控制布局绘制和进行资源回收,这些都是Fragment的好处,以后有机会再谈,今天,我们想讨论的是Activity页面之间跳转时,互相传值的方法选择。
我们知道,像int,long,double等基本类型和String都可以直接使用Intent类提供的putExtra方法直接打包传递,但很多时候,我们要传递的可能是一个实体类的对象,要传递一个实体类对象,有二种办法,标记类实现Serializable接口 或者 添加代码实现Parcelable接口,注意的是Serializable接口没有任何实际方法需要实现,它只是一个标记,标记可以进行序列化。Serialiable是Java提供的序列化接口,它将对象按规则转化为字节队列,字节队列可以进行网络传输,这样可以让java的对象跨环境的进行传输,序列化只能序列化成员变量,而静态变量和方法不会被序列化,transient关键字修饰的变量也不会被序列化。Java中反序列化时通过SerialVersionUID来判断是否能够反序列化,所以需要序列化的类最好都能给出一个固定的SerialVersionUID值,如下
而Parcelable是Android提供的接口,它主要是通过writeToParcel(),将需要持久化的字段保存到一个Parcel对象里面,然后通过CREATOR
从Parcel对象中,取出相应的字段,完成对象的恢复,很明显这里Parcelable有它的优势,需要保存哪些字段我们可以自由控制,因为写接口暴露给我们了,需要恢复哪些字段,我们同样可以控制,所以相对于Serializable,存储的代价小很多,因为Serializable需要保存很多额外的字段来保证反序列化能够成功。
现在我们还是通过一个具体的实例来介绍这二种Activity传值的基本使用方法。假设,我们现在有一个商品Good的列表,Good类是这样的
第一个需求是点击列表的一个cell,跳转到Good的详情页,即我们需要将点击对应的Good对象传递到详情Activity。第二个需求是点击任何一个cell,将全部的Good信息传递到详情Activity,即传递一个Good数组。
我们先来看第一个需求,先用Serializable的方法,发送很简单
接收对象也很简单
我们再来使用Parcelable接口来传递,先定义一个类ParcelableGood
发送数据也很简单
接收也同样类似
第一个需求很简单就搞定了,我们再来搞定第二个需求,传Good的数组给详情Activity,如果使用Serializable的话,Intent没有提供putExtra直接传递Good数组的重载方法,所以我们需要做一个包装类,我新建一个WrapGood类如图
这样就可以直接传递一个WrapGood,间接达到传递Good数组的目的,
接收数据
因为Intent提供了putExtra方法直接传递Parcelable数组的重载,所以可以直接使用,
从Intent中取出Parcelable数组更简单
现在为止Good里面的属性都是基本类型或者String,当然它的属性也可以是另外一个实体类,假设是GoodExtra类,这个时候如果要用Serializable序列化,GoodExtra也必须要标记Serializable接口。如果要使用Parcelable,GoodExtra同样要实现我们上面介绍的writeToParcel 和 CREATOR。
最后我们来做一个总结,上面已经介绍了在Android开发中Serializable和Parcelable的用法,我们推荐使用Parcelable,理由大致有3个:1.Parcelable是Android 框架提供给我使用的,Google提供了比较好的接口和文档支持,例如上面的putExtra,就有对Parcelable数组的重载方法。2. Parcelable效率更高,Parcelable底层实现是内存的copy,速度很快,Serializable是IO操作,而且会用到反射,相对比较慢,国外有人测试过,Parcelable比Serializable从序列化到传输到反序列化,平均要快10倍左右。3.最后一个原因也是最重要的原因,Parcelable要序列化哪些字段,我们完全可以控制,而且还可以在其中加入各种转换,修饰,因为写接口暴露给我们了,我们可以自由定制,而Serializable就显的比较笨拙,而且需要一些额外的字节来存储类的信息,当然Serializable使用起来要更简单。这些都是它们在理论上的比较,项目中绝大多数场景,二者都可以完全胜任,具体用哪个,见仁见智吧~~