8

如何使用 JNI 从 C 访问 Android 资产,例如 .txt 文件?

我正在尝试“file:///android_asset/myFile.txt”和本地“myFile.txt”,在 jni 文件夹中使用 C 实现文件复制 myFile.txt。

4

2 回答 2

11

资产的问题是您不能直接将它们作为文件访问。这是因为资产是直接从 APK 中读取的。它们在安装时不会解压缩到给定的文件夹。

从 Android 2.3 开始,有一个用于访问资产的 C API。看看<android/asset_manager.h>和 中的assetManager字段<android/native_activity.h>。不过我从未使用过它,如果您不依赖本机活动,我不确定您是否可以使用此资产管理器 API。无论如何,这不适用于 Android 2.2 及更低版本。

所以我看到了三个选项:

  • 您可以将资产提取到某个目录中,但这会占用额外的空间
  • 您可以(捆绑并)使用 libzip 之类的东西以纯 C 语言从 APK 中读取资产。
  • 或者,为了避免捆绑额外的库,我个人的偏好是使用 JNIInputStreamAssetManager.open(). 它需要一些代码,但效果很好。
于 2011-01-24T09:03:56.857 回答
2

如果由于需要调用需要文件名的 C/C++ 库而无法使用 AssetManager C API,则可以使用原始资源。

唯一的缺点是它需要在运行时复制到应用程序的数据 (temp) 目录中。

将文件放在 res/raw

将要从本机代码中读取的文件放在res/raw目录中。

制作副本

在运行时,将文件从复制res/raw/myfile.xmldata目录:

File dstDir = getDir("data", Context.MODE_PRIVATE);
File myFile = new File(dstDir, "tmp_myfile.xml");
FileMgr.copyResource(getResources(), R.raw.my_file, myFile);

现在传递给本机代码的文件名是myFile.getAbsolutePath()

复制资源(rsrcId,dstFile)

public static File copyResource (Resources r, int rsrcId, File dstFile) throws IOException
{
    // load cascade file from application resources
    InputStream is =  r.openRawResource(rsrcId);
    FileOutputStream os = new FileOutputStream(dstFile);

    byte[] buffer = new byte[4096];
    int bytesRead;
    while ((bytesRead = is.read(buffer)) != -1)
        os.write(buffer, 0, bytesRead);
    is.close();
    os.close();

    return dstFile;
}
于 2014-06-25T21:49:45.937 回答