能使用 AIDL 实现跨进程传输一个 2M 大小的文件吗?

898 阅读3分钟

Hi 大家好,我是 DHL,大厂程序员,公众号:ByteCode ,在美团、快手、小米工作过。搞过逆向,做过性能优化,研究过系统,擅长鸿蒙、Android、Kotlin、性能优化、职场分享。

来自微信小程序「猿面试」每日分享一道大厂面试题,涉及 JavaAndroid鸿蒙和ArkTS设计模式算法和数据结构 等内容。


在 Android 系统中,AIDL 是 Android 中实现跨进程通信 (Inter-Process Communication) 的一种方式。AIDL 的传输数据机制基于 Binder 实现的,

Binder 是一种进程间通信(IPC)机制,用于在不同进程之间传递数据。Binder 事务(Transaction)是指通过 Binder 进行的数据传输操作。Binder 事务分为同步事务和异步事务两种类型。

  • 同步事务:发送方等待接收方处理完成后再继续执行。通常用于请求-响应模式。
  • 异步事务:发送方不等待接收方处理完成,立即返回继续执行。通常用于通知或事件传递。

同步事务缓冲区的大小限定在 1MB 左右,异步事务缓冲区的大小是该内存的一半。源码如下所示。

#define BINDER_MAX_ALLOC_SIZE (1 * 1024 * 1024)

void binder_alloc_init(struct binder_proc *proc) {
    proc->free_space = BINDER_MAX_ALLOC_SIZE;
    proc->free_async_space = BINDER_MAX_ALLOC_SIZE / 2;
}

如果传输超过 1M 的文件就会报 android.os.TransactionTooLargeException 异常,为了解决这个问题,可以使用匿名共享内存进行大文件传输。

共享内存是进程间通信的一种方式,通过映射一块公共内存到各自的进程空间来达到共享内存的目的。

Android 中的匿名共享内存 (Ashmem) 是基于 Linux 共享内存的实现的,相对于 Linux 的共享内存,Ashmem 对内存的管理更加精细化,并且添加了互斥锁。

匿名共享内存的大小,受限于虚拟内存的大小,在 32 位上,用户空间最大可用内存空间为 3GB,而在 64 位设备上,匿名共享内存的大小则可以更大,通常可以达到 512GB。

因此我们可以使用 MemoryFile 实现了共享内存的传递。它可以让多个进程操作同一块内存区域,这样可以绕过 Binder 的传输大小限制。

更多大厂面试题,欢迎前往微信搜索小程序 「猿面试」 查看。微信小程序 (猿面试) 包含了 Java、Android、鸿蒙和ArkTS设计模式算法和数据结构 相关内容,

更多面试题