Qt for Android JNI:java.lang.NoSuchMethodError

时间:2018-05-04 10:30:49

标签: java android qt java-native-interface

我正在尝试从Java获取一个String数组并在我的Qt Android C ++中使用它(最终在我的QML代码中),但是我得到了以下运行时错误(即崩溃):

<input name="uploadfile" multiple="" style="position: absolute; right: 0px; margin: 0px; padding: 0px; font-size: 480px; font-family: sans-serif; cursor: pointer; height: 100%; z-index: 16777270;" type="file">

{
    "_opts": {
        "url": "/wps/web/app_dev.php/ajax-upload",
        "dropzone": "",
        "dragClass": "",
        "form": "",
        "overrideSubmit": true,
        "cors": false,
        "withCredentials": false,
        "progressUrl": false,
        "sessionProgressUrl": false,
        "nginxProgressUrl": false,
        "multiple": true,
        "multipleSelect": true,
        "maxUploads": 3,
        "queue": true,
        "checkProgressInterval": 500,
        "keyParamName": "APC_UPLOAD_PROGRESS",
        "sessionProgressName": "PHP_SESSION_UPLOAD_PROGRESS",
        "nginxProgressHeader": "X-Progress-ID",
        "customProgressHeaders": {},
        "corsInputName": "XHR_CORS_TARGETORIGIN",
        "allowedExtensions": [
            "jpg",
            "jpeg",
            "gif"
        ],
        "accept": "",
        "maxSize": 1024,
        "name": "uploadfile",
        "data": {},
        "noParams": true,
        "autoSubmit": true,
        "multipart": true,
        "method": "POST",
        "responseType": "json",
        "debug": false,
        "hoverClass": "hover",
        "focusClass": "focus",
        "disabledClass": "",
        "customHeaders": {},
        "encodeHeaders": true,
        "autoCalibrate": true,
        "button": null
    },
    "_queue": [
        {
            "id": "a1696f281-6b04-442e-887c-fba95a148d1f",
            "file": {},
            "name": "1.jpg",
            "ext": "jpg",
            "btn": {},
            "size": 25
        }
    ],
    "_active": 0,
    "_disabled": false,
    "_maxFails": 10,
    "_progKeys": {},
    "_sizeFlags": {},
    "_btns": [
        {}
    ],
    "_manDisabled": false,
    "_overBtn": {},
    "_input": {}
}

Java代码如下:

W System.err: java.lang.NoSuchMethodError: no static method 
"Lcom/test/myTest/JniTest;.getSSIDList(V)[Ljava/lang/String;"

C ++代码是:

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;

        return fibonacci(n-1)+fibonacci(n-2);
    }

    public static String[] getSSIDList()
    {
        List<String> ssidList = new ArrayList<String>();
        ssidList.add("string 1");
        ssidList.add("string 2");

        String[] strings = new String[ssidList.size()];
        strings = ssidList.toArray(strings);//now strings is the resulting array

        return strings;
    }
}

void AndroidInterface::test() { //qDebug() << fibonacci(4); //this works qDebug() << getSSIDList(); //this crashes with the error above } int AndroidInterface::fibonacci(int n) { return QAndroidJniObject::callStaticMethod<jint>("com/test/myTest/JniTest" , "fibonacci" , "(I)I" , n); } QStringList AndroidInterface::getSSIDList() { QAndroidJniObject stringArray = QAndroidJniObject::callStaticObjectMethod("com/test/myTest/JniTest" , "getSSIDList" , "(V)[Ljava/lang/String;"); jobjectArray objectArray = stringArray.object<jobjectArray>(); QAndroidJniEnvironment qjniEnv; const int n = qjniEnv->GetArrayLength(objectArray); qDebug() << "Got jobjectArray of length:" << n; // correct for (int i = 0; i < n; ++i) { qDebug() << "Iteration:" << i; jobject element = qjniEnv->GetObjectArrayElement(objectArray, i); qDebug() << "Got jobject of type:" << qjniEnv->GetObjectClass(element); // ... qjniEnv->DeleteLocalRef(element); } QStringList list; return list; } 的当前实现只有一个测试虚拟主体。

我在QML中有一个按钮调用上面的getSSIDList()代码,该代码适用于AndroidInterface::test()方法,但是fibonacci()方法崩溃并出现上述错误。

我做错了什么?谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

嗯,您没有为本机方法提供正确的JNI签名。我们在V中不需要 (V)[Ljava/lang/String; ,但我们需要([Ljava/lang/String;)V

手工制作正确的C / C ++签名是有可能的,但是很难,但幸运的是,你不需要这样做。

Android Studio,将为您提供帮助。

如果您没有在IDE中内置此功能,请使用 javah 实用程序从Java类中提取标头。即使您实际使用 Kotlin 或其他一些与JVM兼容的语言,这也能正常工作。

请注意,计划在下一个主要JDK版本中删除 javah 工具。该工具已被JDK 8中添加到 javac '-h'选项取代。