跨进程传输大图片有哪些方案:
1. 将图片保存在固定的位置,将存储位置信息跨进程发送给其他进程,其他的进程读取图片文件
这样做的缺点,在于进程需要首先写文件,然后再读文件,性能低下;
2. 通过IPC的方式转发图片数据
IPC方式传递图片的方式:
Binder是Android提供的一种方式,类型共享内存的方式,使用方便,性能较高,但传输的数据有大小限制;Socket和管道传递数据会涉及到至少两次数据拷贝,当数据量大的时候性能低下,除此之外,Socket和管道对单次发送的数据量也是有限制的;
共享内存性能较高,对数据没有大的限制。
在跨进程传输数据的时候,我们需要考虑的两个问题:
当我们使用Intent跨进程传输数据的时候,数据量要是太大,会抛出TransactionTooLargeException的异常,这个异常表示两个Client的进行交互式,事物占用的内存过大,该异常发生的一些情况和解决方法:
上面是通过Intent来跨进程传递一个Bitmap,当mBitmap占用的内存过大的时候,就会抛出TRansactionTooLargeException的异常。
上面这种将Bitmap直接塞到Intent中然后传输的方式会抛出异常,下面这种方式传输同样的Bitmap则不会抛出异常:
如上面的代码,我们通过Intent传递一个Binder对象,接收端在收到Binder对象之后,通过调用BInder对象的getBitmap方法,同样可以获得传输的Bitmap,却不会造成异常。
当我们调用putParcelable传递Bitmap(Bitmap是实现了Parcelable接口的,可以进行序列化的)的时候,系统自动将allowFds设为false,禁止使用文件描述符,bitmap的传输不能利用共享内存的方式,只能将Bitmap拷贝Binder的缓存区,导致缓存区超限,需要申请的内存大于了Binder初始化的1M内存空间的限制,这样就会抛出TransactionTooLargeException的异常;
当我们使用putBinder的方式传递Bitmap的时候,系统是会将allowFds设置为true,运行带fd描述字符的,当传递数据的时候,首先会判断当前数据是否小于16K,小于16KB的时候会直接使用Binder的缓存空间,而当大于16KB的时候,则开辟一个ashmem,映射出一块内存,该数据会保存到ashmem中,在Intent中之写入一个fd的文件描述符,这样即使传输的数据再大,Intent中传输的也只是该资源的文件描述符。而ashmem就是利用了共享内存,在发送端和接收端之间映射同一块内存,无需多次拷贝,提高了数据传输的性能。