您现在的位置是:网站首页> C/C++
QT Android 调用JAVA代码
- C/C++
- 2021-04-19
- 1010人已阅读
1.写一个普通的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();
}
下一篇:Qt C++和Java相互调用