【发布时间】:2011-01-24 08:26:49
【问题描述】:
如何使用 JNI 从 C 访问 Android 资产,例如 .txt 文件?
我正在尝试“file:///android_asset/myFile.txt”,并在本地尝试“myFile.txt”,并在 jni 文件夹中使用 C 实现文件复制 myFile.txt。
【问题讨论】:
标签: android c java-native-interface assets
如何使用 JNI 从 C 访问 Android 资产,例如 .txt 文件?
我正在尝试“file:///android_asset/myFile.txt”,并在本地尝试“myFile.txt”,并在 jni 文件夹中使用 C 实现文件复制 myFile.txt。
【问题讨论】:
标签: android c java-native-interface assets
资产的问题是您不能直接将它们作为文件访问。这是因为资产是直接从 APK 中读取的。它们不会在安装时解压缩到给定的文件夹中。
从 Android 2.3 开始,有一个用于访问资产的 C API。查看<android/asset_manager.h> 和<android/native_activity.h> 中的assetManager 字段。不过我从来没有使用过这个,如果你不依赖原生活动,我不确定你是否可以使用这个资产管理器 API。无论如何,这不适用于 Android 2.2 及更低版本。
所以我看到了三个选项:
AssetManager.open() 返回的 Java InputStream 对象中读取 C 中的数据。它需要一些代码,但效果很好。【讨论】:
如果您无法使用 AssetManager C API,因为您需要调用需要文件名的 C/C++ 库,则可以使用原始资源。
唯一的缺点是它需要在运行时复制到应用程序的数据 (temp) 目录中。
将要从本机代码读取的文件放在res/raw 目录中。
在运行时,将文件从res/raw/myfile.xml 复制到data 目录:
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()
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;
}
【讨论】:
asset 文件夹中读取了一个文件,然后使用FileOutputStream 编写了该文件。我的问题是FileOutputStream保存的文件路径是什么。