使用Qt/C++通过JNI调用Java代码.FindClass找不到类

 形同陌路2502906543 发布于 2023-02-07 13:38

我是JNI的新手,这是我第一个尝试从C++调用Java代码的程序.我正在使用Qt 5.2,我正在编写一个Android应用程序.

我无法找到我的java类并将其加载到我的C++程序中.我已经在堆栈溢出和其他地方阅读了很多帖子,这似乎是一个常见的问题,但我还没能解决我的问题..

我也不确定Java VM是否已正确设置,因为QAndroidJniEnvironment上的Qt文档很少.

我正在寻找一个如何找到我的java类的解决方案.我也很欣赏代码其他部分的一般反馈(我假设可能会有更多错误).

错误消息:

Starting remote process.D/dalvikvm(24911): GC_CONCURRENT freed 384K, 5% free 9180K/9596K, paused 1ms+2ms, total 15ms
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360
I/Qt      (24911): Network start
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360
I/Qt      (24911): qt start
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtMessageDialogHelper'
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): Shared lib '/data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so' already loaded in same CL 0x428b2360
D/dalvikvm(24911): Trying to load lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360
D/Qt      (24911): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment.
D/dalvikvm(24911): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360, skipping init
W/Qt      (24911): kernel\qcoreapplication.cpp:416 (QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, uint)): WARNING: QApplication was not created in the main() thread.
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtNativeInputConnection'
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtExtractedText'
I/Adreno-EGL(24911): : EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13
D/Qt      (24911): fontdatabases\basic\qbasicfontdatabase.cpp:246 (static QStringList QBasicFontDatabase::addTTFile(const QByteArray&, const QByteArray&)): FT_New_Face failed with index 0 : 90 
D/Qt      (24911): ..\AndroidTest\jnimathcppwrapper.cpp:18 (jniMathCppWrapper::jniMathCppWrapper()): JniMath class not found 
D/Qt      (24911): ..\AndroidTest\jnimathcppwrapper.cpp:43 (int jniMathCppWrapper::eleven()): Enter eleven 
F/libc    (24911): Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1), thread 24933 (ple.AndroidTest)

Java类:

package org.app.test;
public class JniMath {

    public JniMath()
    {

    }

    public int eleven()
    {
        return 11;
    }
}

.pro文件:

# Add more folders to ship with the application, here
folder_01.source = qml/AndroidTest
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01

# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =

# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp #\
#    jnimathcppwrapper.cpp

# Installation path
# target.path =

# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()

RESOURCES += \
    resources.qrc


QT += androidextras

OTHER_FILES += \
    android/src/org/app/test/JniMath.java

HEADERS += #\
#    jnimathcppwrapper.h

android {
    SOURCES += jnimathcppwrapper.cpp
    HEADERS += jnimathcppwrapper.h
}

main.cpp中:

#include 
#include "qtquick2applicationviewer.h"
#include "jnimathcppwrapper.h"
#include 
#include 

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/AndroidTest/main.qml"));
    viewer.showExpanded();

    jniMathCppWrapper *test = new jniMathCppWrapper();

    qDebug() << QString::number(test->eleven());

    return app.exec();
}

jnimathcppwrapper.h:

#ifndef JNIMATHCPPWRAPPER_H
#define JNIMATHCPPWRAPPER_H

#include 

class jniMathCppWrapper
{
public:
    jniMathCppWrapper();
    int eleven();

private:
    jobject jniMathObject;
};

#endif // JNIMATHCPPWRAPPER_H

jnimathcppwrapper.cpp:

#include "jnimathcppwrapper.h"
#include 
#include 
#include 

static jclass jniMathClassID = 0;
static jmethodID jniMathConstructorMethodID = 0;
static jmethodID jniMathElevenMethodID = 0;

jniMathCppWrapper::jniMathCppWrapper()
{
    QAndroidJniEnvironment qjniEnv;

    //Get JniMath class ID.
    jniMathClassID = qjniEnv->FindClass("android/src/org/app/test/JniMath");
    if(jniMathClassID == NULL)
    {
        qDebug() << "JniMath class not found";
        return;
    }

    //Get constructor method ID
    jniMathConstructorMethodID = qjniEnv->GetMethodID(jniMathClassID, "", "void(V)");
    if(jniMathConstructorMethodID == NULL)
    {
        qDebug() << "JniMath constructor not found";
        return;
    }

    //Create new Java object and calling the selected constructor.
    jniMathObject = qjniEnv->NewObject(jniMathClassID, jniMathConstructorMethodID);
    if(jniMathObject == NULL)
    {
        qDebug() << "JniMath Java object could not be constructed";
        return;
    }
}

int jniMathCppWrapper::eleven()
{
    QAndroidJniEnvironment qjniEnv;

    qDebug() << "Enter eleven";

    //Get eleven method ID
    jniMathElevenMethodID = qjniEnv->GetMethodID(jniMathClassID, "eleven", "void(V)");
    if(jniMathElevenMethodID == NULL)
    {
        qDebug() << "JniMath class, eleven method not found";
        return 9;
    }

    jint res = qjniEnv->CallIntMethod(jniMathObject, jniMathElevenMethodID);

    return (int) res;
}

项目结构:

在此输入图像描述

编辑:

我也尝试了一种导致同样错误的不同方法:

QAndroidJniObject *myJavaClass = new QAndroidJniObject("android/src/org/app/test/JniMath");

if(myJavaClass->isValid())
{
    qDebug() << "Class found!";
}
else
{
    qDebug() << "Class NOT found!";
}

当尝试加载java/lang/String时,上述两种方法都会找到该类.

编辑:

错误日志:

D/Qt      ( 3385): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment.
D/dalvikvm( 3385): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b67f8
D/Qt      ( 3385): ..\AndroidTest\jnimathcppwrapper.cpp:68 (jint JNI_OnLoad(JavaVM*, void*)): Class NOT found 
D/AndroidRuntime( 3385): Shutting down VM
W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8)
E/AndroidRuntime( 3385): FATAL EXCEPTION: main
E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385
E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath
E/AndroidRuntime( 3385):    at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3385):    at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3385):    at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3385):    at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744)
E/AndroidRuntime( 3385):    at android.app.Activity.performCreate(Activity.java:5231)
W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8)
E/AndroidRuntime( 3385): FATAL EXCEPTION: main
E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385
E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath
E/AndroidRuntime( 3385):    at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3385):    at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3385):    at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3385):    at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522)
E/AndroidRuntime( 3385):    at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744)
E/AndroidRuntime( 3385):    at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 3385):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 3385):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime( 3385):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime( 3385):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime( 3385):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime( 3385):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 3385):    at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 3385):    at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 3385):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3385):    at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 3385):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 3385):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 3385):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 3385): Caused by: java.lang.ClassNotFoundException: Didn't find class "org.app.test.JniMath" on path: DexPathList[[zip file "/data/app/org.qtproject.example.AndroidTest-1.apk"],nativeLibraryDirectories=[/data/app-lib/org.qtproject.example.AndroidTest-1, /vendor/lib, /system/lib]]
E/AndroidRuntime( 3385):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
E/AndroidRuntime( 3385):    at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
E/AndroidRuntime( 3385):    at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
E/AndroidRuntime( 3385):    ... 21 more

评论:为什么这个问题不重复(Alex Cohn)

毫无疑问,这里的根问题与Android JNI中任何线程的FindClass相同,但这里提出的问题是一个非常不同的问题,IMO.在笔者不是在寻找从本地线程访问的类加载器的通用方式.他(或她)正在寻找一种简单有效的方法来从基于Qt的本机代码访问Java回调.因此,关于类加载器如何在Android中工作以及如何修补它的所有讨论都与他无关.如果作者另有说法,我很乐意同意将此问题视为重复

更新:这个问题甚至与JNI线程无关

请考虑之前的评论无效.这个问题与多线程无关.这就是如何设置Android Qt应用程序,以便它可以使用自定义Java类,类似于示例.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有