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

Qt for Android JNI报错:java.lang.NoSuchMethodError问题求助

解决Qt Android C++调用Java静态方法时的NoSuchMethodError问题

咱先从最明显的问题说起——你贴的Java代码里根本没实现getSSIDList这个静态方法啊!错误日志里说找不到Lcom/test/myTest/JniTest;.getSSIDList(V)[Ljava/lang/String;,就是因为JNI在你的JniTest类里找不到对应方法,直接抛出了错误。

第一步:补全Java类里的getSSIDList方法

先把缺失的静态方法补上,如果你需要返回String数组,参考下面的示例代码:

package com.test.myTest;

import java.util.ArrayList;
import java.util.List;

public class JniTest {
    public static int fibonacci(int n) {
        if(n<0) return -1;
        else if(n==0 || n==1) return n;
        else return fibonacci(n-1)+fibonacci(n-2);
    }

    // 新增你需要的getSSIDList静态方法
    public static String[] getSSIDList() {
        // 这里可以写你的业务逻辑,比如获取WiFi列表
        List<String> ssidList = new ArrayList<>();
        ssidList.add("HomeWiFi");
        ssidList.add("OfficeWiFi");
        // 把List转成String数组返回
        return ssidList.toArray(new String[0]);
    }
}

第二步:确保JNI调用的方法签名完全匹配

JNI对方法签名的要求非常严格,哪怕一点小错误都会导致找不到方法。在Qt C++里调用时,要注意这几点:

  • 包名和类名要对应:用斜杠代替点,即com/test/myTest/JniTest
  • 方法名大小写完全一致:必须是getSSIDList
  • 签名要正确:无参数的话是(),返回String数组的签名是[Ljava/lang/String;(注意末尾的分号不能丢)

给你一个完整的Qt C++调用示例,转成QStringList后可以直接给QML使用:

#include <QAndroidJniEnvironment>
#include <QDebug>
#include <QStringList>

QStringList getSSIDListFromJava() {
    QStringList result;
    JNIEnv *env = QAndroidJniEnvironment();

    // 查找JniTest类
    jclass jniTestCls = env->FindClass("com/test/myTest/JniTest");
    if (!jniTestCls) {
        qDebug() << "ERROR: 找不到JniTest类";
        return result;
    }

    // 获取getSSIDList的静态方法ID
    jmethodID getSSIDListMethod = env->GetStaticMethodID(jniTestCls, "getSSIDList", "()[Ljava/lang/String;");
    if (!getSSIDListMethod) {
        qDebug() << "ERROR: 找不到getSSIDList方法";
        env->DeleteLocalRef(jniTestCls);
        return result;
    }

    // 调用静态方法获取String数组
    jobjectArray jSsidArray = (jobjectArray)env->CallStaticObjectMethod(jniTestCls, getSSIDListMethod);
    if (!jSsidArray) {
        qDebug() << "ERROR: 调用getSSIDList返回空";
        env->DeleteLocalRef(jniTestCls);
        return result;
    }

    // 把Java String数组转成QStringList
    int arrayLength = env->GetArrayLength(jSsidArray);
    for (int i = 0; i < arrayLength; ++i) {
        jstring jSsid = (jstring)env->GetObjectArrayElement(jSsidArray, i);
        const char *ssidUtf8 = env->GetStringUTFChars(jSsid, nullptr);
        if (ssidUtf8) {
            result.append(QString::fromUtf8(ssidUtf8));
            env->ReleaseStringUTFChars(jSsid, ssidUtf8);
        }
        env->DeleteLocalRef(jSsid);
    }

    // 释放JNI局部引用,避免内存泄漏
    env->DeleteLocalRef(jSsidArray);
    env->DeleteLocalRef(jniTestCls);

    return result;
}

第三步:检查Qt Android项目配置

  • 确保你的JniTest.java文件放在Qt项目的android/src/com/test/myTest目录下,对应包名的目录结构,这样编译时才能被正确打包进APK。
  • 如果你的getSSIDList是用来获取WiFi列表的,记得在AndroidManifest.xml里添加必要权限:
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- Android 6.0+需要这个权限才能扫描WiFi -->
    

最后再提几个容易踩的坑

  • 方法名大小写敏感:Java是区分大小写的,别把getSSIDList写成GetSSIDList或者其他变体。
  • 签名格式别写错:返回String数组的签名是[Ljava/lang/String;,不是[Ljava/String;或者其他写法。
  • 记得释放JNI引用:JNI的局部引用如果不手动释放,可能会导致内存泄漏甚至崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 11:04:07