qt中调用sdk包流程、方法、注意事项详细说明

qt是以c++为基础语言的编程工具,如果想调用其他语言已经写好的接口,比如java、或者是用java语言导出的jar包,要用到jni技术。
JNI是Java Native Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++)。它实现了java与其他语言的相互调用。在qt中,qt利用原有jni技术,封装出了一个完整的类:QAndroidJniObject,专用于在qt中调用java和jar包。
在qt中如果想调用此类,首先需要android构建环境,这些网上有详细过程,配置好,确保可以在android上跑程序。才可以在qt中使用QAndroidJniObject此类。
一、环境搭建
1、模块与头文件
在pro文件中添加模块:QT += androidextras
添加头文件: #include <QtAndroidExtras/QAndroidJniObject>
#include <QtAndroidExtras/QAndroidJniEnvironment>
2、android文件的创建
![在这里插入图片描述](https://img-blog.csdnimg.cn/20181121185049498.?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMjc4NTY0,size_16,color_FFFFFF,t_70
当android环境搭建好之后,在“项目”中会出现android的构建套件,
“Build Android APK”栏中,Android栏中的“Create Templates”,点击后其他文件一栏会生成一个android文件夹,下面有一系列关于android的文件,我们把需要调用的java文件放在这个文件夹内即可,具体方法如下:
(1)当直接调用.java文件时,在工程文件android文件夹下面创建src文件夹,下面再创建文件夹,名字要和你所要调用的java文件中的package 后面名字一致。把调用的.java文件放在此文件夹下,再在工程里面,添加现有文件即可。
(2)当调用.jar文件时,sdk包中包含的文件是由java导出的.jar文件以及携带的一些.so动态库文件,使用时一律放在android下面创建的libs文件夹内,具体路径根据sdk包里说明创建。
二、简单例子说明
.java

package jni;
public class jniDemo
{
private static int Num = 1;
private static String tmpStr = "123";
public static void setInt(int num) { 
Num = num; 
}
public static int getInt(){
return Num;
}
public static void setString(String str){
tmpStr = str;
}
public static String getString(){
return tmpStr;
} 
}

java中一个非常简单的类,有两个属性,int型和string型,方法有四个,set和get,现在我们在qt中利用jni调用此类的方法,实现在qt中对它的属性进行设置和获取。
.h

namespace Ui {
class Jni_main;
}
class Jni_main : public QMainWindow
{
Q_OBJECT
public:
explicit Jni_main(QWidget *parent = 0);
~Jni_main();
void JavaJniInt(int num);
int UseJavaToInt();
void JavaString(QString s);
QString UseJavaToString();
private slots:
void on_pushButton_clicked();
private:
Ui::Jni_main *ui;
int q;
QString strzzz;
};

.cpp

Jni_main::Jni_main(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Jni_main)
{
ui->setupUi(this);
JavaJniInt(20);
q = UseJavaToInt();
JavaString("zza");
strzzz = UseJavaToString();
}
void Jni_main::JavaJniInt(int num){
QAndroidJniObject::callStaticMethod<void>("jni/jniDemo","setInt","(I)V",num);
ui->label_3->setText(QString::number(100));
}
int Jni_main::UseJavaToInt(){
return QAndroidJniObject::callStaticMethod<jint>("jni/jniDemo","getInt","()I");
}
void Jni_main::JavaString(QString s){
QAndroidJniObject strTmp = QAndroidJniObject::fromString(s);
QAndroidJniObject::callStaticMethod<void>("jni/jniDemo","setString","(Ljava/lang/String;)V",strTmp.object<jstring>());
}
QString Jni_main::UseJavaToString(){
QAndroidJniObject str = QAndroidJniObject::callStaticObjectMethod("jni/jniDemo","getString","()Ljava/lang/String;");
ui->label_3->setText(str.toString());
return str.toString();
}
Jni_main::~Jni_main()
{
delete ui;
}
void Jni_main::on_pushButton_clicked()
{
ui->label->setText(QString::number(q));
ui->label_2->setText(strzzz);
//#endif
}

三、QAndroidJniObject类中各个方法使用说明
在qt中调用java代码,构造java对象,大部分类型的对象,都要转化为想通的类型QAndroidJNIObject,才能在qt与java之间相互使用,int、double、void等除外。
在这个模块中还有一个QAndroidJniEnvironment类 代表jni环境,也就是通用的jni技术中的JNIEnv。但是我们目前主要用到QAndroidJniObject,
其中的主要方法主要分为三类:java对象的构建、java静态方法(类方法)的调用、实例方法的调用。
1、构造java对象
利用jni技术建立的一切对象均为QAndroidJniObject类型,比如如果要构造一个string类型的对象:QAndroidJniObject str(“java/lang/String”);
用这种方法创建了一个string类型的jni对象 并且str为空,类比于qt中的QString str;直接赋值时可以写为
QAndroidJniObject str =QAndroidJniObject ::from(“aaa”);
此时类比于QString str = “aaa”;
java中的类一般都会有构造函数利用构造函数创建对象时就遵循 QAndroidJniObject(const char * className)的方式
如:QAndroidJniObject intent(“android/content/Intent”);
这就构造了一个android中提供的类型intent的对象,这个包名地址是android内部提供,定义时不知道具体可以自己查。
如果是自己定义的类,包名则为路径,从你libs 或 src文件夹后面的路径开始,直到类的名字,用"/“隔开,比如你在libs下面有个Javatest的文件夹,里面有个.jar文件,文件中有个名为JavaTest的类,构造对象时:QAndroidJniObject MyTestObject(“Javatest/JavaTest”);
当构造函数有参数时:
QAndroidJniObject(const char * className, const char * signature, …)
如JavaTest类构造时需要传入一个int类型的参数:
jint num = 123;
QAndroidJniObject MyTestObject(“Javatest/JavaTest”,”(I)V",num);
其中I V 分别代表int void 。 这种写法代表入参和出参
(传入值)返回值。
如果有string类型时,标识比较特殊,因为string类型是java中的一个类,所以这个标识要用java中的标识:“Ljava/lang/String;”
如果有自己定义的对象时,用"Ljava/lang/Object;"
后面的参数要调用.object()方法,如:
QAndroidJniObject MyTestObject(“Javatest/JavaTest”,
“(Ljava/lang/String;)V”,
str.object());
2、调用实例方法
QAndroidJniObject 提供了下列方法以方便我们调用 Java 实例方法:

  1. T callMethod(const char * methodName) const
  2. T callMethod(const char * methodName, const char * signature, …) const
  3. QAndroidJniObject callObjectMethod(const char * methodName) const
  4. QAndroidJniObject callObjectMethod(const char * methodName, const char * signature, …) const
    其中1、2之间以及3、4之间不多解释,区别在于有无传入参数,而1、2与3、4之间区别在于方法名中有无object,这个object是指返回值,也就是说,你调用的java方法中返回值是什么类型的决定了用哪种方法。
    当你的方法返回值为int、double、void等基础类型,也就是不是对象类型的时候,要调用1、2里面的callMethod,要注意要在方法名后面标注返回值的类型,比如:
    test.callMethod(“setName”,"(Ljava/lang/String;)V",str.object());
    这句代码就代表一个你构造的对象test,调用它类中的方法"setName",需要传入string,返回值为空。
    当你的方法返回值为对象时,要用3、4里面的callObjectMethod,这时要用一个QAndroidJniObject类型的变量去接收它,比如:
    QAndroidJniObject s = test.callObjectMethod(“getName”,"()Ljava/lang/String;");
    这句就代表test的调用类中"getName"方法,无传入值,返回值为string,但是要注意,这里返回的值类型均为jni对象类型,如果后面要用string,需要:s.toString()把它转换回string类型。
    3、调用java类方法(静态方法)
    java中类方法是属于类的,不需要构造对象就可以调用。
    QAndroidJniObject 提供了下列静态方法来调用 Java 类方法:
    Ÿ T callStaticMethod(const char * className, const char * methodName)
    Ÿ T callStaticMethod(const char * className, const char * methodName, const char * signature, …)
    Ÿ T callStaticMethod(jclass clazz, const char * methodName)
    Ÿ T callStaticMethod(jclass clazz, const char * methodName, const char * signature, …)
    Ÿ QAndroidJniObject callStaticObjectMethod(const char * className, const char * methodName)
    Ÿ QAndroidJniObject callStaticObjectMethod(const char * className, const char * methodName, const char * signature, …)
    Ÿ QAndroidJniObject callStaticObjectMethod(jclass clazz, const char * methodName)
    Ÿ QAndroidJniObject callStaticObjectMethod(jclass clazz, const char * methodName, const char * signature, …)
    这些在返回类型上与实例方法大同小异,只是在调用上有稍微不同。类方法的第一个参数一定是类所在的路径,实例方法不需要路径是因为在构造对象时已经声明,上面给出的简单示例中全部都是调用static方法,比如:
    QAndroidJniObject::callStaticMethod(“jni/jniDemo”,“getInt”,"()I");
    这句代码代表调用jni文件夹下jniDemo类的“getInt”方法,传入值为空,返回值为int。
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值