您现在的位置是:网站首页> C/C++

QT Android 调用JAVA代码

  • C/C++
  • 2022-03-25
  • 956人已阅读
摘要

下面是完整程序


1.写一个普通的JAVA类

//MyJavaClass.java

public 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_OBJECT

public:

    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();     //返回值为bool

 

private:

    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;          //类ID

static 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;   //构造函数ID

 

 

 

JavaHandler::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;

}


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();

}

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


Top