我已经在 Linux 中编写了一个简单的共享内存 C 程序。
如何在 Android 中使用共享内存(或者我应该称之为“ashmem?”)?
我希望你能给我一个分步指南。
4 回答
这对我有用:
1)打开一个 MemoryFile 对象:mFile;
2) 创建一个服务,使用 mmap 将其映射到 ashem;
3) 使用 ParcelFileDescriptor pfd 将本机文件描述符 (fd) 返回到绑定到您的服务的客户端;
4)为接受fd的客户端创建JNI,并使用mmap映射成灰烬;
5) 使用这个 fd 创建 InputStream,现在客户端可以使用 InputStream 对象读/写相同的内存区域。
此链接显示如何将 MemoryFile 映射到 ashem。此链接显示如何通过 AIDL 和 ParcelFileDescriptor 向客户端发送本机文件描述符 (fd) 到客户端。
在服务器端,您需要创建:
1) 通过 ParcelFileDescriptor 将本机 fd 传递给客户端的服务和 AIDL;2) 服务端执行映射的 JNI。
在客户端: 1) 绑定到服务的方法,然后调用服务获取本机fd;2) 将 fd 映射到 ashem 的 JNI。
然后服务和客户端可以读取/写入映射的内存区域。
一个过程通过以下步骤创建一个新的 ashmem 区域:
(1) 打开设备文件“/dev/ashmem”并获取文件描述符。(2) 调用ASHMEM_SET_NAME ioctl 设置ashmem 名称。它似乎是虚拟设备文件,因此如果将其命名为“my_mem”,文件名将更改为“/dev/ashmem/my_mem”。(3) 调用 ASHMEM_SET_SIZE ioctl 设置 ashmem 大小,以字节为单位。
cutils 库有一个函数“ashmem_create_region”,它将这些步骤包装成一个函数调用:
int fd = ashmem_create_region("my_mem", PAGE_SIZE * 20);
文件描述符可以与其他进程共享。Android 提供了一种特殊的方式来在表亲进程之间共享文件描述符,使用另一个名为“binder”的服务。然后每个进程都映射文件:
char *map = mmap(NULL, PAGE_SIZE * 20, PROT_READ|PROT_WRITE,
MAP_SHARED, fd, 0);
而且,瞧!即时共享内存。
在 Android 中使用 binder IPC。我认为绑定器使用所有进程共享的内核内存进行进程间通信。
好吧,如果你想使用共享内存 API,这里有一个解决方案 https://github.com/pelya/android-shmem
就像魔术一样,它完美地工作。您可以使用 shmget()、shmat() 和 shmdt() API 无缝地在独立进程中使用 android 中的共享内存。试试看。