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

QAndroidJniObject调用Java方法取jlong报NoSuchMethodError如何解决

根因说明

Java侧getAmount()方法的返回值为装箱类型java.lang.Long,而非基本数据类型long,你调用时传入的方法签名()J对应的是返回基本long类型的方法,所以会触发方法找不到的异常。

基于QAndroidJniObject的解决方案

有两种可选实现:

  • 方案1:修改Java侧代码,将返回值改为基本类型long,原有C++调用逻辑无需调整
// Java侧修改后代码
public long getAmount() {
    return this.mAmount;
}
  • 方案2:不修改Java代码,调整C++侧调用逻辑,先获取装箱的Long对象,再调用其longValue()方法转为基础jlong类型
static void onOperationStatusApprovedReceived(JNIEnv *env, jobject /*thiz*/,jobject statusObj)
{
    QAndroidJniObject callbackObj(statusObj);
    qDebug()<<"mId"<<callbackObj.callObjectMethod<jstring>("getID").toString();
    // 先获取装箱类型Long对象
    QAndroidJniObject amountObj = callbackObj.callObjectMethod("getAmount", "()Ljava/lang/Long;");
    // 调用Long类的longValue方法转成基本jlong类型
    jlong amount = amountObj.callMethod<jlong>("longValue", "()J");
    qDebug()<<"mAmount"<< amount;
}
原生JNI extern C实现方案

完全可以使用原生JNI替代QAndroidJniObject实现需求,QAndroidJniObject本身就是对JNI接口的Qt封装,原生实现示例如下:

extern "C"
JNIEXPORT void JNICALL
// 注意方法名需按JNI规范,替换为你Java侧声明approvedStatusSendToQt方法的类全路径
Java_com_xxx_xxxx_approvedStatusSendToQt(JNIEnv *env, jclass thiz, jobject statusObj)
{
    // 获取OperationData类引用
    jclass cls_operation = env->FindClass("com/sim/lib/operation/OperationData");
    // 调用getID方法
    jmethodID mid_getId = env->GetMethodID(cls_operation, "getID", "()Ljava/lang/String;");
    jstring id_jstr = static_cast<jstring>(env->CallObjectMethod(statusObj, mid_getId));
    const char* id_cstr = env->GetStringUTFChars(id_jstr, nullptr);
    qDebug() << "mId" << QString::fromUtf8(id_cstr);
    env->ReleaseStringUTFChars(id_jstr, id_cstr);

    // 调用getAmount方法获取装箱Long对象
    jmethodID mid_get_amount = env->GetMethodID(cls_operation, "getAmount", "()Ljava/lang/Long;");
    jobject amount_obj = env->CallObjectMethod(statusObj, mid_get_amount);
    // 转基本jlong类型
    jclass cls_long = env->FindClass("java/lang/Long");
    jmethodID mid_long_value = env->GetMethodID(cls_long, "longValue", "()J");
    jlong amount = env->CallLongMethod(amount_obj, mid_long_value);
    qDebug() << "mAmount" << amount;

    // 释放JNI局部引用,避免内存泄漏
    env->DeleteLocalRef(cls_operation);
    env->DeleteLocalRef(id_jstr);
    env->DeleteLocalRef(amount_obj);
    env->DeleteLocalRef(cls_long);
}

原生JNI实现需要注意手动管理JNI引用,方法命名需符合JNI规范(类路径的点替换为下划线,下划线、特殊字符需要转义)。


内容的提问来源于stack exchange,提问作者Artem Redko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03