敞开生长之旅!这是我参与「日新方案 2 月更文挑战」的第 18 天,点击检查活动详情

前语

最近想不出什么比较好的内容,可是碰到一个没毕业的小老弟问的问题,那就借机说说这个事。Intent如何传大数据?为什么是简略的说,由于这背面深化的话,有很多底层的细节包含规划思维,我也不敢说彻底懂,但我知道当你用Intent传大数据报错的时候应该怎样处理,而且简略聊聊这背面所涉及到的东西。

Intent传大数据

平常或许不会发生这种问题,但比方我之前是做终端设备的,我的设备每秒都会生成一些数据,而长期的话数据量天然大,这时当我跳到别的一个页面运用intent把数据传过去的时候,就会报错

咱们调用

intent.putExtra("key", value) // value超越1M

会报错

android.os.TransactionTooLargeException: data parcel size xxx bytes

这儿的xxx就是1M左右,告知你传输的数据大小不能超越1M,有些话咱也不敢胡说,有点怕误人子弟。我这儿是凭印象说的,假如有大佬看到我说错,请狠狠的纠正我。

这个错误描绘是这么描绘,但真的是限死1M吗,提到这个,就不得不提相同东西,Binder机制,先不要跑,这儿不会详细讲Binder,仅仅提一嘴。

提到Binder那就会联系到mmap内存映射,你能够先简略了解成内存映射是分配一块空间给内核空间和用户空间共用,假如仍是不好了解,就简略想成分配一块空间通讯用,那在android中mmap分配的空间是多少呢?1M-4K。

那是不是说Intent传输的数据超越1M-4K就会报错,理论上是这样,但实际没到这个值,比方0.8M也或许会报错。所以你不能去走极限操作,比方你的数据到了1M,你觉得只要削减点数据,减到8K,应该就能过了,也许你自己测验是正常的,可是这很危险。

所以能不传大数据就不要传大数据,它的规划初衷也不是为了传大数据用的。假如真要传大数据,也不要走极限操作。

那怎样办,切莫着急,请听我慢慢讲。就这个Binder它是什么玩意,它是Android中独特的进程通讯的方法,而Linux中进程通讯的方法,在Android中相同也适用。进程间通讯有很多方法,Binder、管道、同享内存等。为什么会有这么多种通讯方法,由于每种通讯方法都有自己的特色,要在不同的场合运用不同的通讯方法。

为什么要提这个?由于要看懂这个问题,你需求知道Binder这种通讯方法它有什么特色,它适合大量的数据传输吗?那你Binder又与我Intent何关,你抓周树人找我鲁迅干嘛~~所以这时候你就要知道Android四大组件之间是用什么方法通讯的。

有点扯远了,现在能够来说说结论了,Binder没办法传大数据,我就1M不到你想怎样?当然它不止1M,仅仅Android在运用时约束了它只能最多用1M,内核的最大约束是4M。又有点扯远了,你不要想着怎样把约束扩大到4M,不要往这方面想。前面说了,不同的进程通讯方法,有自己的特色,适用于某些特定的场景。那Binder不适用于传输大数据,我同享内存行不行?

所以就有了处理办法

bundle.putBinder()

有人或许一看觉得,这有什么不同,这在表面上看差别不大,实则内部大大的不同,bundle.putBinder()用了同享内存,所以能传大数据,那为什么这儿会用同享内存,而putExtra不是呢?想搞清楚这个问题,就要看源码了。 这儿就不深化去剖析了,我怕劝退,不是劝退你们,是劝退我自己。有些东西是这样的,你要自己去看懂,看个大约就差不多,可是你要讲出来,那就要看得细致,而有些细节的确会劝退人。所以想了解为什么的,能够自己去看源码,不想看的,就知道这是怎样一回事就行。

那还有没有其它方法呢?当然有,你不明白同享内存,你写到本地缓存中,再从本地缓存中读取行不行?

办法有很多,假如你不知道这个问题怎样处理,你找不到你觉得可行的处理方案,甚至能够经过逻辑经过流程的方法去绕开这个问题。可是你要知道为什么会出现这样的问题,假如你没接触过进程通讯,没接触过Binder,让你看一篇文章就能看懂我觉得不切实际,可是至少得知道是怎样一回事。

比方我只说bundle.putBinder()能处理这个问题,你一试,的确能处理,可是不知道为什么,你又怕会不会有其它问题。虽然这篇文章我一直在打擦边球,没有提任何的原理,但我觉得仍是能大约让人知道为什么bundle.putBinder()能处理Intent传大数据,你也就能放心去用了。