iQt*_*iQt 8 c++ java java-native-interface qt android
我是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): <qeglDrvAPI_eglInitialize:320>: 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)
Run Code Online (Sandbox Code Playgroud)
Java类:
package org.app.test;
public class JniMath {
public JniMath()
{
}
public int eleven()
{
return 11;
}
}
Run Code Online (Sandbox Code Playgroud)
.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
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中:
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "jnimathcppwrapper.h"
#include <QDebug>
#include <QString>
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();
}
Run Code Online (Sandbox Code Playgroud)
jnimathcppwrapper.h:
#ifndef JNIMATHCPPWRAPPER_H
#define JNIMATHCPPWRAPPER_H
#include <QtAndroidExtras>
class jniMathCppWrapper
{
public:
jniMathCppWrapper();
int eleven();
private:
jobject jniMathObject;
};
#endif // JNIMATHCPPWRAPPER_H
Run Code Online (Sandbox Code Playgroud)
jnimathcppwrapper.cpp:
#include "jnimathcppwrapper.h"
#include <QtAndroidExtras>
#include <QDebug>
#include <jni.h>
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, "<init>", "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;
}
Run Code Online (Sandbox Code Playgroud)
项目结构:

编辑:
我也尝试了一种导致同样错误的不同方法:
QAndroidJniObject *myJavaClass = new QAndroidJniObject("android/src/org/app/test/JniMath");
if(myJavaClass->isValid())
{
qDebug() << "Class found!";
}
else
{
qDebug() << "Class NOT found!";
}
Run Code Online (Sandbox Code Playgroud)
当尝试加载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
Run Code Online (Sandbox Code Playgroud)
毫无疑问,这里的根问题与Android JNI中任何线程的FindClass相同,但这里提出的问题是一个非常不同的问题,IMO.在笔者不是在寻找从本地线程访问的类加载器的通用方式.他(或她)正在寻找一种简单有效的方法来从基于Qt的本机代码访问Java回调.因此,关于类加载器如何在Android中工作以及如何修补它的所有讨论都与他无关.如果作者另有说法,我很乐意同意将此问题视为重复
请考虑之前的评论无效.这个问题与多线程无关.这就是如何设置Android Qt应用程序,以便它可以使用自定义Java类,类似于示例.
小智 0
你的java源目录是否复制到android-build目录中?源文件夹中的 android 文件夹需要在 qmake 变量 ANDROID_PACKAGE_SOURCE_DIR 中列出,请参阅:http://qt-project.org/doc/qt-5/deployment-android.html#qmake-variables