AIDL调用中byte[]超1MB触发DeadObjectException,Bitmap却不触发的原因?
跨进程AIDL大数据传输问题
问题描述
假设有两个进程,从进程A的Activity向进程B的Service发起AIDL调用(比如byte[] getBytes()),获取返回的byte[]数据。当byte[]大小超过1MB时,会触发以下异常:
W Error = android.os.DeadObjectException: Transaction failed on small parcel; remote process probably died W at android.os.BinderProxy.transactNative(Native Method) W at android.os.BinderProxy.transact(BinderProxy.java:571)
将byte[]封装在自定义Parcelable类中也会出现同样问题,这符合Binder事务的官方数据限制。但如果AIDL接口返回的是数据量超过1MB的Bitmap(比如Bitmap getBitmap()),却不会触发该异常。
请问这是为什么?另外,若要传输超过1MB的数据(如音频、视频等非图片文件),首选方案是什么?
问题解答
1. 为什么Bitmap超过1MB不会触发异常?
Bitmap跨进程传输时,根本没把像素数据直接塞进Binder的Parcel缓冲区,而是用了共享内存(Ashmem)的机制:
- Binder只传输Bitmap的基础元数据(宽高、格式等)以及共享内存的文件描述符
- 两个进程直接共用同一块内存区域,不需要把整个Bitmap的数据拷贝到Binder事务缓冲区里,自然碰不到1MB的Binder事务大小限制
而byte[]或者自定义Parcelable里的byte[],是直接把数据序列化到Parcel中,当数据量超过1MB上限时,就会触发异常。
2. 音频、视频这类非图片大文件的跨进程传输首选方案
推荐按以下优先级选择方案:
- 共享内存(Ashmem):和Bitmap的原理一致,把文件数据写入共享内存,AIDL仅传递共享内存的文件描述符,两个进程直接操作同一块内存,完全避免数据拷贝,效率最高
- 本地文件中转:把大文件写入本地存储(内部/外部存储均可),AIDL中传递文件路径,接收方直接读取文件。这种方式实现最简单,适合超大文件场景,缺点是需要处理存储权限,且读写文件存在一定耗时
- 拆分分批传输:把大文件拆分成多个小于1MB的
byte[]块,通过多次AIDL调用分批传输,最后在接收方拼接完整数据。这种方式无需额外权限,但代码实现复杂,多次IPC调用也会增加开销
内容的提问来源于stack exchange,提问作者code
相关产品推荐
相关产品推荐

