Miss Parcelable

Miss Parcelable序列化将数据结构或对象转换成二进制串的过程。反序列化将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程频繁的IO操作,所以消耗比较大,但是实现方式简单serialVersionUID是一个privatestaticfinallong型ID,通常是对象的哈希码你可以使用serialver这个JDK工具来查看序列化对象的serialVersionUID。SerialVerionUID用于对象的版本控制。也可以在类文件中指定serialVersionUID

序列化
将数据结构或对象转换成二进制串的过程。

反序列化
将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

serialVersionUID
是一个 private static final long 型 ID,
通常是 对象的哈希码
你可以使用 serialver 这个 JDK 工具来查看序列化对象的 serialVersionUID。
SerialVerionUID 用于对象的版本控制。
也可以在类文件中指定 serialVersionUID。
不指定 serialVersionUID的后果是,
当你添加或修改类中的任何字段时,
则已序列化类将无法恢复,
因为 为新类和旧序列化对象生成的 serialVersionUID 将有所不同。
Java 序列化过程依赖于正确的序 列化对象恢复状态的,
并在序列化对象序列版本不匹配的情况下引发

Serializable
通过IO对硬盘操作,速度较慢
大小不受限制
大量使用反射,产生内存碎片
频繁的IO操作,所以消耗比较大,但是实现方式简单
可将数据持久化方便保存,所以在需要保存或网络传输数据时选择Serializable

Parcelable
直接在内存操作,效率高,性能好,内存开销小
一般不能超过1M,修改内核也只能4M
内存间数据传输时推荐使用Parcelable
在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable
Parcelable不能使用在要将数据存储在磁盘上的情况,
因为Parcelable不能很好的保证数据的持续性在外界有变化的情况下。
尽管Serializable效率低点,但此时还是建议使用Serializable

序列化的概念:
将数据结构或对象转换成二进制串的过程

反序列化
将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

持久化:
把数据结构或对象 存储起来 硬盘

序列化方案:

  1. Serializable Java的序列化方案

  2. Parcelable Android独有

  3. json,xml,protbuf … 广义的序列化

  4. 必须要一个public的无参构造函数
    Java.io.InvalidClassException: com.example.xuliehuademo01.demo06$User; no valid constructor

  5. serialVersionUID 更新

    private void writeObject(ObjectOutputStream out) throws IOException {

    out.defaultWriteObject();
    out.writeObject(getSex());
    out.writeInt(getId());
    }

     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
         setSex((String)in.readObject());
         setId(in.readInt());
     }
    

反序列化后的对象会重新调用构造函数吗?
不会, 因为是从二进制直接解析出来的. 适用的是 Object 进行接收再强转, 因此不是原来的那个对象

序列化与反序列化后的对象是什么关系?
是一个深拷贝, 前后对象的引用地址不同

Android 为什么要设计 bundle 而不是使用 HashMap 结构?
bundle 内部适用的是 ArrayMap, ArrayMap 相比 Hashmap 的优点是, 扩容方便, 每次扩容是原容量的一半, 在[百量] 级别, 通过二分法查找 key 和 value (ArrayMap 有两个数组, 一个存放 key 的 hashcode, 一个存放 key+value 的 Entry) 的效率要比 hashmap 快很多, 由于在内存中或者 Android 内部传输中一般数据量较小, 因此用 bundle 更为合适
serializableVersionUID 的作用是?
用于数据的版本控制, 如果反序列化后发现 ID 不一样, 认为不是之前序列化的对象

Android 中 intent/bundle 的通信原理以及大小限制?
Android 中的 bundle 实现了 parcelable 的序列化接口, 目的是为了在进程间进行通讯, 不同的进程共享一片固定大 小的内存, parcelable 利用 parcel 对象的 read/write 方法, 对需要传递的数据进行内存读写, 因此这一块共享内存不能 过大, 在利用 bundle 进行传输时, 会初始化一个 BINDER_VM_SIZE 的大小 = 1 * 1024 * 1024 – 4096 * 2, 即便通过 修改 Framework 的代码, bundle 内核的映射只有 4M, 最大只能扩展到 4M.
更详细的看leo老师的binder课程

为何 Intent 不能直接在组件间传递对象而要通过序列化机制?
因为 Activity 启动过程是需要与 AMS 交互, AMS 与 UI 进程是不同一个的, 因此进程间需要交互数据, 就必须序列化
更详细的看zero老师的ams课程

序列化与持久化的关系和区别?
序列化是为了进程间数据交互而设计的, 持久化是为了把数据存储下来而设计的

Serializable性能分析
Serializable是Java中的序列化接口,其使用起来简单但开销较大
(因为Serializable在序列化过程中使 用了反射机制,故而会产生大量的临时变量,从而导致频繁的GC),
并且在读写数据过程中,它是通 过IO流的形式将数据写入到硬盘或者传输到网络上。

Parcelable性能分析
Parcelable则是以IBinder作为信息载体,在内存上开销比较小,
因此在内存之间进行数据传递时,
推荐 使用Parcelable,而Parcelable对数据进行持久化或者网络传输时操作复杂,一般这个时候推荐使用 Serializable。

Parcelable的性能要强于Serializable
在内存的使用中,前者在性能方面要强于后者
后者在序列化操作的时候会产生大量的临时变量
(原因是使用了反射机制)从而导致GC的频繁调用,
因此在性能上会稍微逊色
Parcelable是以Ibinder作为信息载体的.
在内存上的开销比较小,因此在内存之间进行数据传递的时候,
Android推荐使用Parcelable,既然是内存方面比价有优势,
那么自然就要优先选择.
在读写数据的时候,Parcelable是在内存中直接进行读写,
而Serializable是通过使用IO流的形式将数据读写入在硬盘上.
但是:虽然Parcelable的性能要强于Serializable,
但是仍然有特殊的情况需要使用Serializable,而不去使用Parcelable,
因为Parcelable无法将数据进行持久化,
因此在将数据保存在磁盘的时候,仍然需要使用后者,
因为前者无法很好的将数据进行持久化.
(原因是在不同的Android版本当中,Parcelable 可能会不同,
因此数据的持久化方面仍然是使用Serializable)

Parcel的简介
在介绍之前我们需要先了解Parcel是什么?
Parcel翻译过来是打包的意思,
其实就是包装了我们需要传输的数据,
然后在Binder中传输,也就是用于跨进程传输数据
简单来说,Parcel提供了一套机制,
可以将序列化之后的数据写入到一个共享内存中,
其他进程通过 Parcel可以从这块共享内存中读出字节流,
并反序列化成对象,下图是这个过程的模型。
Parcel可以包含原始数据类型(用各种对应的方法写入,比如writeInt(),writeFloat()等),
可以包含 Parcelable对象,它还包含了一个活动的IBinder对象的引用,
这个引用导致另一端接收到一个指向这个 IBinder的代理IBinder。
Parcelable通过Parcel实现了read和write的方法,从而实现序列化和反序列化,

今天的文章Miss Parcelable分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/9484.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注