Android 通过匿名共享内存传输Parcelable对象列表

在Android组件时间进行通信或者进程间进行通信时,有时会出现TransactionTooLargeException这个异常,这个java异常是在jni层抛出的,可见android_util_binder.cpp中关于这个异常的解释,大概意思是“传输太大是最常见的原应,但是不是唯一原应,也有可能是FD,应该就是描述binder驱动的文件描是符关闭了,以及可能其他原因”,这里暂且只关注常见的。我们在组件间通信时会使用intent传输一些参数,一步小心会带上一些大对象,组件启动到底层都会通过ActivityManagerService这个守护神,属于进程间通信,最终都需要使用Parcel将数据写入内核中由Binder开辟的一块区域,Binder驱动open的区域一般为4M,而进程间传输的数据大小会限制在1M,而且这1M是被这个进程所有正在进行的binder通信所共同使用的,所以一般情况下也就达不到1M,可想而知,我们要是传个Bitmap啥的,离奔溃也就不远了。

       大对象怎么传输呢,我们一般会想到分批传输,文件传输,效率都不是很高,Android系统给我们提供了另一种方法-匿名共享内存的方法

        Ashmem原理上的理解很简单,就是将一块物理内存通过内核开辟并映射到不同的进程的虚拟地址空间,这样不同进程就可以直接对这块内存区域进行读写操作,共享 而且高效。

使用上Android在java层面给我们提供了访问接口MemoryFile类;

1.实例化一个 MemoryFile对象

2.写入 bytes 数据,这里借助parcel来进行Parcelable对象到bytes的转化

3.将文件描述符传到目标进程

4.remote 进程通过文件描述符读取流数据,再借助parcel来将bytes 来转化为Parcelable对象

虽然操作起来似乎也不是那么方便,但是传输效率上和实用性上还是经得住考验的,

1.大小就不用说了,几M的对象都可以轻松应对

2.效率上,20000个普通对象,6M大小,发送时编码加写操作,接收时读操作和解码,耗时都在几百ms,还可以接受

demo: github.com/mc2012/Android-AshMemory/tree/master

你可能感兴趣的:(Android 通过匿名共享内存传输Parcelable对象列表)