I want to write some bytes to a shared memory. This is done in my application1. From my another application: application2 I want to access that shared memory to read the written bytes. For this purpose I tried using android's MemoryFile class. I am stuck as how to refer to the same shard memory between two different application. I am also now confused if memoryFile is used for the same purpose or not. http://developer.android.com/reference/android/os/MemoryFile.html this link I found regarding the topic. Thanks in advance. Krishna
-
2I think the "official" way to go is to use a content provider, or use a regular file on external storage. – Mister Smith Nov 17 '11 at 10:09
-
1+1 for ContentProvider / ContentResolver – Guillaume Nov 17 '11 at 10:16
-
the size of the content is large (3-4 MB) and I need fast read write so I need something like shared memory. Also please if you could help me understanding the use of memoryFile in Android. – nits.kk Nov 17 '11 at 11:50
-
4The official API for MemoryFile is pretty utterly **craptastic** (_as usual_) - hidden away are however `#getParcelFileDescriptor()` (which transfers nicely across processes) and `#getFileDescriptor()`. – Jens Nov 17 '11 at 11:54
3 Answers
If you want some cross-process use with MemoryFile
you can use the following fugly method:
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import java.io.FileDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MemoryFileUtil {
private static final Method sMethodGetParcelFileDescriptor;
private static final Method sMethodGetFileDescriptor;
static {
sMethodGetParcelFileDescriptor = get("getParcelFileDescriptor");
sMethodGetFileDescriptor = get("getFileDescriptor");
}
public static ParcelFileDescriptor getParcelFileDescriptor(MemoryFile file) {
try {
return (ParcelFileDescriptor) sMethodGetParcelFileDescriptor.invoke(file);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static FileDescriptor getFileDescriptor(MemoryFile file) {
try {
return (FileDescriptor) sMethodGetFileDescriptor.invoke(file);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static Method get(String name) {
try {
return MemoryFile.class.getDeclaredMethod(name);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
What you should be looking at is the #getParcelFileDescriptor(MemoryFile)
method which you can return from an implementation of ContentProvider#openFile(Uri, String)
.

- 16,853
- 4
- 55
- 52
-
1I suspect my code throws exception at MemoryFile.class.getDeclaredMethod("getParcelFileDescriptor"); but it doesnt really goto catch clause I knew only after putting a breakpoint there – duckduckgo Sep 22 '13 at 11:49
-
I really don't get it. If all you are doing is passing an FD, why use ashmem at all? You can just use ParcelFileDescriptor.createPipe() and write any local data you want across it. No ashmem required. – Jeffrey Blattman Oct 11 '16 at 18:22
I suspect memory files don't have the getParcelFileDescriptor method. When I commented this getParcelFileDescriptor related methods and use getFileDescriptor. It worked nicely.
import java.io.FileDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.os.MemoryFile;
/**
* Invoke hidden methods using reflection
*
*/
public class MemoryFileUtil {
private static final Method sMethodGetFileDescriptor;
static {
sMethodGetFileDescriptor = get("getFileDescriptor");
}
public static FileDescriptor getFileDescriptor(MemoryFile file) {
try {
return (FileDescriptor) sMethodGetFileDescriptor.invoke(file);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
private static Method get(String name) {
try {
return MemoryFile.class.getDeclaredMethod(name);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
And created File descriptor from memory file.
FileDescriptor fd = MemoryFileUtil.getFileDescriptor(memFile);

- 701
- 10
- 26
MemoryFile can be used to map to physical memory. The result file descriptor (fd) can be passed to client (memory sharing side). The client can map the same native fd to the same memory region. The memory can then be shared using the native fd, which can be mapped to java layer using InputStream.
Please refer to this link for more details:
Sharing memory using ashem.