Intent传递对象时为什么要序列化

来源:互联网 发布:中文版装修设计软件 编辑:程序博客网 时间:2024/06/08 11:19

大家都知道进行Android开发的时候,无法将对象的引用传给Activities或者Fragments,我们需要将这些对象放到一个Intent或者Bundle里面,然后再传递。至于怎么实现序列化,反序列化相信网上的帖子一大堆了就不一一阐述了

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

二. 那么为什么要序列化?

序列化的原因基本三种情况: 

1.永久性保存对象,保存对象的字节序列到本地文件中;

2.对象在网络中传递; 

3.对象在IPC间传递。

 三.  Android中的两种序列化机制
第一种: JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设   备保存对象状 态,以及通过网络传输对象等。
第二种:在Android系统中,定位为针对内存受限的设备,因此对性能要求更高,另外系统中采用了新的IPC(进程间通信)机制,必然要求使用性能更出色的对象传输方式。在这样的环境下, Parcel被设计出来,其定位就是轻量级的高效的对象序列化和反序列化机制。
Android中序列化有以下几个特征:
1.整个读写全是在内存中进行,所以效率比JAVA序列化中使用外部存储器会高很多;
2.读写时是4字节对齐的
3.如果预分配的空间不够时,会一次多分配50%;
4.对于普通数据,使用的是mData内存地址,对于IBinder类型的数据以及FileDescriptor使用的是mObjects内存地址。 后者是通过flatten_binder()和 unflatten_binder()实现的,目的是反序列化时读出的对象就是原对象而不用重新new一个新对象。

我写了两个Activity,一个是MainActivity,里面通过intent把一个实现序列化接口的实体类User对象传递过去,

    User user = new User();    user.setId(1);    user.setName("zhangsan");    Intent intent = new Intent();    intent.setClass(this, TwoActivity.class);    intent.putExtra("user", user);    startActivity(intent);            Log.d("main", user+"");

另一个TwoActivity里面,接收这个User对象:
Intent intent = this.getIntent();
User user = (User) intent.getSerializableExtra("user");

    Log.d("two", user+"");

结果:打印出来的两个user指向的不是同一地址 这是为什么呢?

那么好:可以这样理解,当把一个对象从一个地方传到另一个地方,传递的不是引用,它的地址肯定会改变,世界上没有两个相同的地址。更深层次理解应该是传递前的处理:传递前根据该对象序列化,接收后反序列化再重新生成该对象,根据序列化和反序列化的规则,某些特征应该是一样的,包括值。

               putSerializable,是通过对象的序列化和反序列化来实现Activity之间对象的传递的,所以这种方法得到的就是两个完全不一样的对象(Activity2中的对象obj就相当于new了一个新对象,然后将Activity1中的对象obj的值都赋给了它,所以可以说它们的内容是一样的,但是对象不一样。
再说说JAVA中的Serialize机制,译成串行化、序列化……,其作用是能将数据对象存入字节流当中,在需要时重新生成对象。主要应用是利用外部存储设备保存对象状态,以及通过网络传输对象等。   
            假如两个avtivity传递的是一个对象,那么当在TwoActivity里继续操作MainActivity的对象那么必将造成内存泄漏。
2 0
原创粉丝点击