Qt для Android JNI: java.lang.NoSuchMethodError - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь получить массив String из Java и использовать его в моем Qt Android C ++ (и, в конечном счете, в моем коде QML), но я получаю следующую ошибку времени выполнения (то есть сбой):

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

Код Java выглядит следующим образом:

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;
    }
}

Код C ++:

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;
}

Текущая реализация getSSIDList() имеет только тестовое фиктивное тело.

У меня есть кнопка в QML, которая вызывает приведенный выше код AndroidInterface::test(), который работает для метода fibonacci(), но выдает сбой для метода getSSIDList() с ошибкой выше.

Что я делаю не так? Спасибо за вашу помощь!

1 Ответ

0 голосов
/ 08 мая 2018

Ну, вы не предоставили правильную подпись JNI для нативного метода. Нам не нужно V в (V)[Ljava/lang/String;, но нам нужно в ([Ljava/lang/String;)V.

Возможно, но сложно создать правильные сигнатуры C / C ++ для наивных методов вручную, но, к счастью, вам не нужно этого делать.

Android Studio, например, поможет вам в этом.

Если это не встроено в вашу IDE, используйте утилиту javah , чтобы извлечь заголовок из ваших классов Java. Это работает, даже если вы на самом деле используете Kotlin или какой-либо другой JVM-совместимый язык.

Обратите внимание, что инструмент javah планируется удалить в следующем основном выпуске JDK. Инструмент был заменен параметром '-h', добавленным к javac в JDK 8.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...