您的位置:首页 > 编程语言 > Qt开发

QT Android 调用JAVA代码

2016-01-18 21:22 525 查看
了解过QT for Andorid,发现qt 并不是万能的,很多时候还是需要调用JAVA的代码,

网上有一段QT调用 java代码的示例

Qt中调用java的方法

尝试之后发现按他的写法只能调用静态方法(我是QT5.5)

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

完整代码

点我

下面是完整程序

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


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的方法,弹出消息框显示结果
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android qt java