You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中使用Boost转换JSON字符串时应用崩溃问题排查

问题:React Native传递JSON字符串到JNI后应用崩溃无提示

我尝试从React Native的JS代码传递JSON字符串到JNI层读取,但应用启动后直接崩溃,没有任何错误提示。

JS端传递代码

let myJSONString = JSON.stringify({foo: "bar"});

Boost配置的CMakeLists.txt

set(my_boost_dir ${CMAKE_CURRENT_SOURCE_DIR}/libs/ndk_25_boost_1.79.0)

set(MY_BOOST_LIBS_DIR ${my_boost_dir}/libs)
set(MY_BOOST_INC_DIR ${my_boost_dir}/include)


#-----------------------------------------
add_library (libboost_container SHARED IMPORTED)

set_target_properties( libboost_container PROPERTIES IMPORTED_LOCATION
        ${MY_BOOST_LIBS_DIR}/${ANDROID_ABI}/libboost_container.so
        )
#-----------------------------------------


#-----------------------------------------
add_library (libboost_json SHARED IMPORTED)

set_target_properties( libboost_json PROPERTIES IMPORTED_LOCATION
        ${MY_BOOST_LIBS_DIR}/${ANDROID_ABI}/libboost_json.so
        )
#-----------------------------------------


#-----------------------------------------
add_library (libboost_system SHARED IMPORTED)

set_target_properties( libboost_system PROPERTIES IMPORTED_LOCATION
        ${MY_BOOST_LIBS_DIR}/${ANDROID_ABI}/libboost_system.so
        )
#-----------------------------------------
add_library( libboost_chrono SHARED IMPORTED)

set_target_properties(libboost_chrono PROPERTIES IMPORTED_LOCATION
        ${MY_BOOST_LIBS_DIR}/${ANDROID_ABI}/libboost_chrono.so
        )
#-----------------------------------------

include_directories( ${MY_BOOST_INC_DIR}
        )

JNI读取JSON的代码

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/json.hpp>

JNIEXPORT jstring JNICALL
Java_com_ca_com_1gen_1lib_1pers_c_1libs_1core_MyStringToJSON_myStringToJSON(JNIEnv *env,
                                                                               jobject instance,
                                                                               jstring myJSONStringEntity_)
{
    const char *myJSONStringEntity = env->GetStringUTFChars(myJSONStringEntity_, 0);

    // Short alias for this namespace
    namespace pt = boost::property_tree;

    // Create a root
    pt::ptree root;

    // Load the json file in this ptree
    pt::read_json(myJSONStringEntity, root);

    // Read values
    std::string returnVal = root.get<std::string>("foo", 0);

    return returnVal;
}

错误点分析与解决

1. pt::read_json参数使用错误

boost::property_tree::read_json的第一个参数是文件路径,不是JSON字符串。你直接传入JS传递的字符串,它会把这个字符串当作文件路径去读取,必然找不到文件,触发未捕获异常导致崩溃。

要解析JSON字符串,需用std::istringstream把字符串转为流再传入:

std::istringstream json_stream(myJSONStringEntity);
pt::read_json(json_stream, root);

记得包含头文件<sstream>。

2. root.get默认值类型不匹配

root.get<std::string>("foo", 0)里的默认值是整数0,但模板参数是std::string,类型不匹配会引发编译或运行时异常,改为字符串类型的默认值:

std::string returnVal = root.get<std::string>("foo", "default_value");

3. JNI返回值类型错误

你直接返回std::string类型,但JNI函数要求返回jstring,必须用env->NewStringUTF完成转换:

jstring result = env->NewStringUTF(returnVal.c_str());

4. 未释放JNI字符串资源

调用env->GetStringUTFChars后,必须调用env->ReleaseStringUTFChars释放资源,避免内存泄漏:

env->ReleaseStringUTFChars(myJSONStringEntity_, myJSONStringEntity);

5. 未捕获解析异常

Boost Property Tree解析JSON时会抛出异常,JNI层未捕获的异常会直接导致应用崩溃,建议添加try-catch块捕获异常:

6. Boost库未链接到JNI目标

你在CMake中导入了Boost库,但未将它们链接到你的JNI库目标,运行时会找不到符号导致崩溃,需在CMake中添加链接配置:

# 假设你的JNI库目标名为my_jni_lib
target_link_libraries(my_jni_lib
        libboost_container
        libboost_json
        libboost_system
        libboost_chrono
        android
        log
)

修正后的JNI代码

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/json.hpp>
#include <sstream>
#include <string>
#include <stdexcept>

JNIEXPORT jstring JNICALL
Java_com_ca_com_1gen_1lib_1pers_c_1libs_1core_MyStringToJSON_myStringToJSON(JNIEnv *env,
                                                                               jobject instance,
                                                                               jstring myJSONStringEntity_)
{
    const char *myJSONStringEntity = env->GetStringUTFChars(myJSONStringEntity_, nullptr);
    std::string returnVal = "default";

    try {
        namespace pt = boost::property_tree;
        pt::ptree root;
        std::istringstream json_stream(myJSONStringEntity);
        pt::read_json(json_stream, root);
        returnVal = root.get<std::string>("foo", "default");
    } catch (const std::exception& e) {
        returnVal = e.what();
    }

    env->ReleaseStringUTFChars(myJSONStringEntity_, myJSONStringEntity);
    return env->NewStringUTF(returnVal.c_str());
}

内容的提问来源于stack exchange,提问作者Program-Me-Rev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 00:10:41