关于Android共享内存,可以查看下这个资料
https://blog.youkuaiyun.com/goodlixueyong/article/details/53151959
Android中分别提供了C++和Java的访问共享内存的接口
Java层使用MemoryFile
通过fd去标识共享内存
android_os_SharedMemory.cpp里有具体实现
Native层使用了binder封装,
但是
没有提供直接的native层到java层的接口
这里,我们测试通过文件描述符去read共享内存的数据
在native层可以通过MemoryBase类的封装去进行共享内存的读写。
//test ashmem
sp<MemoryHeapBase> heap = new MemoryHeapBase(64, 0, "testmem");
if (heap != NULL)
{
mem = new MemoryBase(heap, 0, 64);
pdata = (int32_t*)mem->pointer();
if (pdata != NULL)
{
*pdata = 1;
}
获取fd
fd = heap->getHeapID();
}
可以把 fd = heap->getHeapID();里的fd传给客户端,
status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code)
{
…
case 3:{
printf("onTransact called, case 3\n");
reply->writeFileDescriptor(fd);
return NO_ERROR;
}
}
在客户端去进行read操作
int fd = -1;
int err = service->transact(3, data, &reply, 0);
if (err == NO_ERROR)
{
fd = reply.readFileDescriptor();
int data = 0;
read(fd, (void*)&data, 4);
可以读取到数据,客户端和服务端的fd对应着内核中的同一个文件表项,如果需要多次读取共享内存中的数据,在一次读结束后,使用
lseek(fd, 0, SEEK_SET)
把文件偏移量重置为0后即可从头再来。
通过fd的传送,可以很方便的实现c++层服务端的共享内存和java层应用的交互。可以让java层跳过jni处理,直接去根据获取到的fd进行流操作获取数据。Java方法中应该有相应的偏移量设置。
目前发现的一个现象,不能使用write方法去写数据
int t = 2000;
int wrt = write(fd, (void*)&t, 4);
if (wrt == -1)
cout << "write failed " << errno << endl;
else
cout << "write " << endl;
报错,write failed 22
errno 22