QT Android 调用JAVA代码

来源:互联网 发布:人工智能创新发展专项 编辑:程序博客网 时间:2024/05/17 02:11

了解过QT for Andorid,发现qt 并不是万能的,很多时候还是需要调用JAVA的代码,
网上有一段QT调用 java代码的示例
Qt中调用java的方法
尝试之后发现按他的写法只能调用静态方法(我是QT5.5)

于是有尝试了其他的方式,写了一个QT调用 Java的 示例代码
完整代码
点我

下面是完整程序

1.写一个普通的JAVA类

//MyJavaClass.javapublic class MyJavaClass{    public static int mystatic(int n)             //静态函数;    {       return n+1;    }    public int getNum()                            //没有参数;    {        return 12345678;    }    public int setNum( int n )                     //有参调用    {        return n;    }    public String getStr(String perfix)                        //返回对象    {        String teststr = new String("hello " + perfix);        return teststr;    }    boolean boolTest()                              //返回bool类型    {        return true;    }}

2.写一个C++类

//testclass.h#include <jni.h>class JavaHandler:public QObject{    Q_OBJECTpublic:    explicit JavaHandler(QObject *parent=0);public:    //Q_INVOKABLE宏说明:因为我测试程序是用qml调用的    //返回值都是String是为了方便我在qml中显示调用结果   Q_INVOKABLE QString mystatic(int num);   //静态方法   Q_INVOKABLE QString getNum(); // 无参   Q_INVOKABLE QString setNum(int num); //有参   Q_INVOKABLE QString getStr(QString perfix);  //参数和返回值都是对象    Q_INVOKABLE QString boolTest();     //返回值为boolprivate:    jobject m_TestObject;       //java对象};

3.C++源程序

这个示例代码的核心是
JNIEXPORT jint JNI_OnLoad(JavaVM vm,void )
基本上是原生JNI的接口,没有用QT提供的QAndroidJniObject 类
这样可以在非QT的环境里稍修改为也可以用

//testclass.cpp#include "testclass.h"static JavaVM* g_javaVM = 0;            //虚拟机指针static jclass g_testClassID   = 0;          //类IDstatic jmethodID g_mystaticID = 0;        //静态方法static jmethodID g_getNumID = 0;          //无参方法static jmethodID g_setNumID = 0;          //有参方法static jmethodID g_getStrID = 0;          //参数和返回值为类对象static jmethodID g_boolTestID = 0;        //返回值为bool型static jmethodID g_constMethodID = 0;   //构造函数IDJavaHandler::JavaHandler(QObject *parent){    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL))    {            qCritical() << "AttachCurrentThread failed";            return;    }    //[] new 一个对象    m_TestObject = env->NewGlobalRef(env->NewObject(g_testClassID,g_constMethodID));    if(!m_TestObject)    {        qCritical() << "Can not create the object";        return;    }    g_javaVM->DetachCurrentThread();}QString JavaHandler::mystatic(int num){    if(!m_TestObject)        return QString("Error");    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL) < 0)    {        return QString("Fail to Attach");    }    jint ret = env->CallStaticIntMethod(g_testClassID,g_mystaticID,num);    g_javaVM->DetachCurrentThread();    return QString::number(ret,10);}QString JavaHandler::getNum(){     if(!m_TestObject)        return QString("Error");    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL) < 0)    {        return QString("Fail to Attach");    }    jint ret = env->CallIntMethod(m_TestObject,g_getNumID);    g_javaVM->DetachCurrentThread();    return QString::number(ret,10);}QString JavaHandler::setNum(int num){     if(!m_TestObject)        return QString("Error");    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL) < 0)    {        return QString("Fail to Attach");    }    jint ret = env->CallIntMethod(m_TestObject,g_setNumID,num);    g_javaVM->DetachCurrentThread();    return QString::number(ret,10);}QString JavaHandler::getStr(QString perfix){    if(!m_TestObject)        return QString("Error");    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL) < 0)    {        return QString("Fail to Attach");    }    jstring str = env->NewString(reinterpret_cast<const jchar*>(perfix.constData()),perfix.length());    jobject retstr = env->CallObjectMethod(m_TestObject,g_getStrID,str);    jstring jstrtemp = (jstring)retstr;   const char *pstr= env->GetStringUTFChars(jstrtemp, 0);    QString rstr(pstr);    g_javaVM->DetachCurrentThread();    return rstr;}QString JavaHandler::boolTest(){     if(!m_TestObject)        return QString("Error");    JNIEnv* env;    if(g_javaVM->AttachCurrentThread(&env,NULL) < 0)    {        return QString("Fail to Attach");    }    jboolean ret = env->CallBooleanMethod(m_TestObject,g_boolTestID);    g_javaVM->DetachCurrentThread();    return (ret?"ture":"false");}JNIEXPORT jint JNI_OnLoad(JavaVM *vm,void *){    JNIEnv *env;    //[1] 指定JNI 版本,利用VM获得 env指针    if(vm->GetEnv(reinterpret_cast<void **>(&env),JNI_VERSION_1_6) != JNI_OK)    {        qCritical() << "Can't get the enviroument";        return -1;    }    //保存获得指针以便在任意上下文中使用    g_javaVM = vm;    //[2] 获取类ID    jclass clazz = env->FindClass("com/MyJavaClass");    if(!clazz)    {        qCritical() << "Can't find class MyJavaClass";        return -1;    }    g_testClassID = (jclass)env->NewGlobalRef(clazz);     // search for its contructor    g_constMethodID = env->GetMethodID(g_testClassID, "<init>", "()V");    if (!g_constMethodID)    {        qCritical()<<"Can't find  class contructor";        return -1;    }    g_mystaticID = env->GetStaticMethodID(g_testClassID,"mystatic","(I)I");    if(!g_mystaticID)    {        qCritical() << "Can't find static method "<< endl;        return -1;    }    g_getNumID = env->GetMethodID(g_testClassID,"getNum","()I");    if(!g_getNumID)    {        qCritical() << "Can't find getNum method "<< endl;        return -1;    }    g_boolTestID = env->GetMethodID(g_testClassID,"boolTest","()Z");    if(!g_boolTestID)    {        qCritical() << "Can't find booltest method "<< endl;        return -1;    }    g_setNumID = env->GetMethodID(g_testClassID,"setNum","(I)I");    if(!g_setNumID)    {        qCritical() << "Can't find setNUM method "<< endl;        return -1;    }    g_getStrID = env->GetMethodID(g_testClassID,"getStr", "(Ljava/lang/String;)Ljava/lang/String;");    if(!g_getStrID)    {        qCritical() << "Can't find GetStr Method "<< endl;        return -1;    }    qDebug() << "JNI Load Success !";    return JNI_VERSION_1_6;}

4.main.cpp及qml文件

//main.cpp#include <QApplication>#include <QQmlApplicationEngine>#include <qqmlfile.h>#include <QQuickTextDocument>#include "testclass.h"int main(int argc, char *argv[]){    QApplication app(argc, argv);     qmlRegisterType<JavaHandler>("java.handler",1,0,"JavaHandler");    QQmlApplicationEngine engine;    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));    return app.exec();}

qml文件是使用qtCreator生成,具体代码不贴了
这里写图片描述

点击按钮分别调用java的方法,弹出消息框显示结果

0 0
原创粉丝点击