By liran bh | 5/15/2016 | General |Beginners

Android Shared Memory

Android Shared Memory

The common mechanism in android to share data between processes is the binder.
We can also use other IPC like unix domain sockets, pipes etc.
The main problem with the above is performance. In some cases we need to share memory between processes to prevent the system from coping data to and from the kernel

Android ashmem

One feature that google added to linux kernel is ashmem. We can create a new region using MemoryFile class or ashmem_create_region on native layer but, for security reasons, we cant open an existing region The solution is to create a service that creates the region and return it to the client via file descriptor. First we declare the service AIDL:

interface IShmService
{
     ParcelFileDescriptor getFD(in String name);
}

The type ParcelFileDescriptor wrap the kernel object to pass it using the binder

The Service Code

The java part of the code is auto generated using aidl utility, to create and map a shared memory (or any other file descriptor object) we need a native code because we need a pointer

 

static jint getFD(JNIEnv *env, jobject thiz, jstring n)
{
     const char *name = (env)->GetStringUTFChars(n,NULL);
 
     jint fd = open("/dev/ashmem",O_RDWR);
 
     ioctl(fd,ASHMEM_SET_NAME,name);
 
     ioctl(fd,ASHMEM_SET_SIZE,4096);
 
     map = (int *)mmap(0,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
     // fill some data for testing purpose
     map[0]=99;
     map[10]=88;
 
     (env)->ReleaseStringUTFChars(path,name);
 
     return fd;
 
}

 

The Service Java Code

The native function returns an integer file descriptor , the java code needs to convert it to ParcelFileDescriptor

public ParcelFileDescriptor getFD(String name) throws RemoteException {
  try {
          int fd = ShmLib.getFD(name); // call to native function
          ParcelFileDescriptor ret=ParcelFileDescriptor.fromFd(fd);
          return ret;
  } catch (IOException e) {
   e.printStackTrace();
  }
 
   return null;
 }

 

The function prototype is generated automatically using aidl and throws RemoteException because it passed through the binder

 

The Client Code -Java

Simply bind to the service (using bindservice and Intent object) and call the above function to get the duplicated file descriptor:

 

ParcelFileDescriptor p = service.getFD("samp");
 
ShmClientLib.init(p.getFd());

 

The Client Code – native

 

Declare a global pointer to hold the shared memory address and use mmap to set it:

 

static void init(JNIEnv *env, jobject thiz, jint fd)
{
 map = (int *)mmap(0,4096,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
}

 

By liran bh | 5/15/2016 | General

{{CommentsModel.TotalCount}} Comments

Your Comment

{{CommentsModel.Message}}

Recent Stories

Top DiscoverSDK Experts

User photo
3355
Ashton Torrence
Web and Windows developer
GUI | Web and 11 more
View Profile
User photo
3220
Mendy Bennett
Experienced with Ad network & Ad servers.
Mobile | Ad Networks and 1 more
View Profile
User photo
3060
Karen Fitzgerald
7 years in Cross-Platform development.
Mobile | Cross Platform Frameworks
View Profile
Show All
X

Compare Products

Select up to three two products to compare by clicking on the compare icon () of each product.

{{compareToolModel.Error}}

Now comparing:

{{product.ProductName | createSubstring:25}} X
Compare Now