what is the use of MemoryFile in android

2019-01-09 06:42发布

问题:

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

回答1:

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).



回答2:

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);


回答3:

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.