【问题标题】:what is the use of MemoryFile in androidandroid中的MemoryFile有什么用
【发布时间】:2011-12-31 04:50:09
【问题描述】:

我想将一些字节写入共享内存。这是在我的应用程序1 中完成的。从我的另一个应用程序:application2 我想访问该共享内存以读取写入的字节。为此,我尝试使用 android 的 MemoryFile 类。我被困在如何在两个不同的应用程序之间引用相同的分片内存。我现在也很困惑 memoryFile 是否用于相同目的。 http://developer.android.com/reference/android/os/MemoryFile.html 这个链接我找到了关于这个话题。 提前致谢。 克里希纳

【问题讨论】:

  • 我认为“官方”的方式是使用内容提供商,或者使用外部存储上的常规文件。
  • +1 用于 ContentProvider / ContentResolver
  • 内容的大小很大(3-4 MB),我需要快速读写,所以我需要共享内存之类的东西。如果你能帮助我理解 memoryFile 在 Android 中的使用,也请。
  • MemoryFile 的官方 API 非常craptastic像往常一样)——但是隐藏起来的是#getParcelFileDescriptor()(它可以很好地跨进程传输)和#getFileDescriptor()

标签: java android memory


【解决方案1】:

如果您想与MemoryFile 进行跨进程使用,您可以使用以下 fugly 方法:

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

您应该查看的是 #getParcelFileDescriptor(MemoryFile) 方法,您可以从 ContentProvider#openFile(Uri, String) 的实现中返回该方法。

【讨论】:

  • 我怀疑我的代码在 MemoryFile.class.getDeclaredMethod("getParcelFileDescriptor");但它并没有真正 goto catch 子句,我只有在放一个断点后才知道
  • 我真的不明白。如果你所做的只是传递一个 FD,为什么还要使用 ashmem?您可以只使用 ParcelFileDescriptor.createPipe() 并在其中写入您想要的任何本地数据。不需要 ashmem。
【解决方案2】:

我怀疑内存文件没有 getParcelFileDescriptor 方法。当我评论这个 getParcelFileDescriptor 相关方法并使用 getFileDescriptor 时。它工作得很好。

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

并从内存文件创建文件描述符。

FileDescriptor fd = MemoryFileUtil.getFileDescriptor(memFile);

【讨论】:

    【解决方案3】:

    MemoryFile 可用于映射到物理内存。结果文件描述符(fd)可以传递给客户端(内存共享端)。客户端可以将相同的本机 fd 映射到相同的内存区域。然后可以使用本机 fd 共享内存,可以使用 InputStream 将其映射到 java 层。

    更多详情请参考此链接:
    Sharing memory using ashem.

    【讨论】:

      猜你喜欢
      • 2013-11-15
      • 1970-01-01
      • 2011-12-15
      • 2011-03-29
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多