专栏名称: 鸿洋
你好,欢迎关注鸿洋的公众号,每天为您推送高质量文章,让你每天都能涨知识。点击历史消息,查看所有已推送的文章,喜欢可以置顶本公众号。此外,本公众号支持投稿,如果你有原创的文章,希望通过本公众号发布,欢迎投稿。
目录
相关文章推荐
鸿洋  ·  Android主线程锁监控的一种方案 ·  2 天前  
stormzhang  ·  打工人维权,难吗? ·  3 天前  
鸿洋  ·  Android多渠道打包指南 ·  3 天前  
鸿洋  ·  systemserver进程监控者--wat ... ·  4 天前  
鸿洋  ·  Room数据库使用一些坑 ·  5 天前  
51好读  ›  专栏  ›  鸿洋

面试题:为什么使用 Bundle 而不使用 HashMap

鸿洋  · 公众号  · android  · 2024-09-05 09:00

正文


本文作者


作者:程序员DHL

链接:

https://juejin.cn/post/7408379631093219379

本文由作者授权发布。


Bundle 内部是由 ArrayMap 实现的,ArrayMap 和 HashMap 是 Android 中常用的两种键值对数据结构,关于它们的区别可以前往微信小程序「猿面试」中查看 「ArrayMap和HashMap的区别」。

这篇文章我们一起来看一下在 Android 中为什么使用 Bundle 而不使用 HashMap。
1
Bundle 相比 HashMap 占用更少内存


Bundle 内部是由 ArrayMap 实现的,ArrayMap 的内部实现是两个数组,一个记录所有 key 的 hashcode 值组成的数组,是从小到大的排序方式,一个存放 key-value。

内部使用二分法进行查找,时间复杂度为 O (log n),但由于数组操作(如插入、删除)需要移动元素,插入和删除的时间复杂度为 O (n),因此只适合于小数据量操作。

ArrayMap 满足条件会扩容后的大小为原来的 1.5 倍,并且有容量收缩机制,当内存使用量不足 1/3 的情况下,内存数组会收紧 50%。

HashMap(1.8)内部则是数组 + 链表 + 红黑树结构,默认大小为 16,超过容量 3/4 的时候,双倍扩容,且没有容量收缩机制,所以占用内存更多,因此 ArrayMap 比 HashMap 占用更少的内存。
2
系统的限制


Activity 之间通过 Intent 传递数据,因为其内部使用了 Binder 通信机制。

由于系统的限制,Binder 事务缓冲区的大小限定在 1MB,这个大小是共享的,所以不能传递大数据,因此使用 Bundle 来传递数据,可以保证更快的速度和更少的内存占用。
3
Parcelable 比 Serializable 性能更好


HashMap 使用 Serializable 进行序列化,而 Bundle 则是使用 Parcelable行序列化。

Serializable

Serializable 是 Java 原生序列化的方式,主要通过 ObjectInputStreamObjectOutputStream 来实现对象序列化和反序列化。

在整个过程中用到了大量的反射和临时变量,会频繁的触发 GC,序列化的性能会非常差。

序列化时需要手动指定 serialVersionUID,用来辅助序列化和反序列化过程的,序列化与反序列化的 serialVersionUID 必须相同才能够使序列化操作成功,如果不显式声明 serialVersionUID,类的任何细节改变,都可能改变默认的 serialVersionUID 这可能导致反序列化失败。

Parcelable

Parcelable 是为了解决了在 Android 中跨进程通信性能差的问题,Parcelable 写入和读取的时候都是采用自定义序列化存储的方式,不需要使用反射来推断它,因此 ParcelableSerializable要快很多。

虽然性能得到提升,但是使用起来比 Serializable要复杂,因此系统封装了 Bundle 类,方便我们进行数据的传输。
4
如何选择 Parcelable 比 Serializable


Serializable 的设计初衷是为了序列化对象到本地文件、数据库、网络流、RMI 以便数据传输,当然这种传输可以是程序内的也可以是两个程序间的。

而 Android 的 Parcelable 的设计初衷是由于 Serializable 效率过低,消耗大,而 Android 中数据传递主要是在内存环境中(内存属于 Android 中的稀有资源),因此 Parcelable 的出现为了满足数据在内存中低开销而且高效地传递问题。

因此 Android 应用程序在内存间数据传输时推荐使用 Parcelable

如果数据持久化存储,推荐使用 Serializable 更加方便,因为 Parcelables 与数据存储一起使用是不安全的,因为数据格式可能会在 Android 版本之间改变。因此在序列化到存储设备或者网络传输方面还是尽量选择 Serializable 接口。



最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!


扫一扫 关注我的公众号

如果你想要跟大家分享你的文章,欢迎投稿~


┏(^0^)┛明天见!