CMake,JNI 提升读取 json 文件 - Android
Posted
技术标签:
【中文标题】CMake,JNI 提升读取 json 文件 - Android【英文标题】:CMake, JNI boost read json file - Android 【发布时间】:2021-12-08 05:46:12 【问题描述】:用boost::property_tree::json_parser::read_json
打开文件的正确方法是什么
当前树:
boost::property_tree::ptree config;
boost::property_tree::json_parser::read_json("conf/file.json", config);
但是我得到了找不到文件的错误
以 boost::wrapexceptboost::property_tree::json_parser::json_parser_error: conf/file.json: 无法打开文件类型的未捕获异常终止
我将如何继续将文件复制到设备中并能够打开它?
【问题讨论】:
检查当前目录是否与您期望的路径匹配。确保配置文件已上传到预期位置。 将文件放入assets
文件夹,并使用JNI Asset library访问它们。
@MarekR 如何确定并检查它是否已上传到所需位置?
@RichardCritten 对 boost 有用吗?
@RichardCritten 如何将InputStream
转换为提升ptree
,不胜感激?
【参考方案1】:
我使用此代码使其工作,基本上你将文件从 android raw
dir 复制到 C++ JNI 代码可以看到的设备上的某个位置。
MainActivity
代码:
private static final String RES_RAW_CONFIG_PATH_ENV_VAR = "RES_RAW_CONFIG_PATH";
private static final String RES_RAW_CONFIG_FILE_NAME = "res_raw_config.json";
@Override
protected void onCreate(Bundle savedInstanceState)
initResRawConfig(true); // this will copy the file
...
private boolean existsInFilesDir(String fileName)
val file = File(filesDir, fileName)
return file.exists()
private void initResRawConfig(boolean forceCopy)
if (existsInFilesDir(RES_RAW_CONFIG_FILE_NAME) && !forceCopy)
Log.d(TAG, "Config file: " + RES_RAW_CONFIG_FILE_NAME + " already exists in " + getFilesDir().toString());
else
copyFileFromResToFilesDir(R.raw.res_raw_config, RES_RAW_CONFIG_FILE_NAME);
Log.d(TAG, "Config file: " + RES_RAW_CONFIG_FILE_NAME + " copied to " + getFilesDir().toString());
// Set Environment Variable to get path from native
try
Os.setenv(RES_RAW_CONFIG_PATH_ENV_VAR, getFilesDir().getAbsolutePath(), true);
catch (ErrnoException e)
e.printStackTrace();
private void copyFileFromResToFilesDir(int fromResId, String toFile)
InputStream is = getResources().openRawResource(fromResId);
byte[] buffer = new byte[4096];
try
FileOutputStream fos = openFileOutput(toFile, Context.MODE_PRIVATE);
int bytes_read;
while ((bytes_read = is.read(buffer)) != -1)
fos.write(buffer, 0, bytes_read);
fos.close();
is.close();
catch (FileNotFoundException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public String getResRawConfigDir()
return getFilesDir().toString();
JNI
代码:
// get file path from java method
std::string getResRawConfigDirFromJava(JNIEnv *env, jobject obj)
jclass clazz = env->GetObjectClass(obj); // or env->FindClass("com/example/myapp/MainActivity");
jmethodID method = env->GetMethodID(clazz, "getResRawConfigDir", "()Ljava/lang/String;");
jobject ret = env->CallObjectMethod(obj, method);
auto jConfigDirPath = (jstring) ret;
return std::string(env->GetStringUTFChars(jConfigDirPath, nullptr));
extern "C" JNIEXPORT jstring
sampleFunc(JNIEnv *env, jobject thiz)
std::string configPath = getResRawConfigDirFromJava(env, thiz);
std::string filePath = configPath + "/" + "res_raw_config.json";
参考:https://github.com/nkh-lab/ndk-config-provider/blob/master/app/src/main/java/com/example/myapp/MainActivity.java
【讨论】:
以上是关于CMake,JNI 提升读取 json 文件 - Android的主要内容,如果未能解决你的问题,请参考以下文章
AndroidStudio2.2 Preview3中NDK开发之CMake和传统 JNI在目录结构和配置文件上的区别(转载)