前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android中怎么跨进程传输大图片

Android中怎么跨进程传输大图片

作者头像
码农帮派
发布2021-01-28 10:07:26
2.8K0
发布2021-01-28 10:07:26
举报
文章被收录于专栏:码农帮派码农帮派

跨进程传输大图片有哪些方案:

1. 将图片保存在固定的位置,将存储位置信息跨进程发送给其他进程,其他的进程读取图片文件

这样做的缺点,在于进程需要首先写文件,然后再读文件,性能低下;

2. 通过IPC的方式转发图片数据

IPC方式传递图片的方式:

  • Binder
  • Socket、管道
  • 共享内存

Binder是Android提供的一种方式,类型共享内存的方式,使用方便,性能较高,但传输的数据有大小限制;Socket和管道传递数据会涉及到至少两次数据拷贝,当数据量大的时候性能低下,除此之外,Socket和管道对单次发送的数据量也是有限制的;

共享内存性能较高,对数据没有大的限制。

在跨进程传输数据的时候,我们需要考虑的两个问题:

  • 1. 性能问题,尽量减少数据拷贝的次数;
  • 2. 内存限制,单次发送的数据量过大会造成内存泄漏。

当我们使用Intent跨进程传输数据的时候,数据量要是太大,会抛出TransactionTooLargeException的异常,这个异常表示两个Client的进行交互式,事物占用的内存过大,该异常发生的一些情况和解决方法:

  • 1. 发送/返回的数据量过大,跨进程通信的过程中,发送数据和接收数据都是通过Buffer承载的,要是占用的内存过大,那么预留给对方的内存就有可能不足,当内存不足的时候,发送/返回数据申请不到足够的内存,就会抛这个异常;
  • 2. BInder缓存申请不到足够的内存缓存空间,应用在启动Binder机制的时候,会穿件1M的缓存空间作为BInder通信的内存空间,所有的Binder公用这1M的内存,要是某个Binder服务占用的内存空间较大,导致其他的Binder无法申请到足够的内存空间,就会抛出这个异常;
  • 3. 对于单个Binder调用数据传输量过大的问题,建议的解决方案是将数据打散分批发送。

上面是通过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就是利用了共享内存,在发送端和接收端之间映射同一块内存,无需多次拷贝,提高了数据传输的性能。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-01-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码农帮派 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档