Qt使用JNI调用Java代码—————附带完整示例

965 阅读3分钟

文章目录

0 背景

在开发Android应用时,有些功能无法使用Qt原生或C++来实现其功能,只能调用java代码来实现。因此就涉及到在Qt中调用java的问题。

调用各个方法结果:

在这里插入图片描述

1 调用准备

在.pro中加入下面代码,因此来提供对Android库的支持

QT += androidextras

两个重要的类:
QAndroidJniEnvironment:实现JNI的环境,用于异常的检查和清除等功能;
QAndroidJniObject:用于调用java方法

2 调用

2.1 调用方法

方法签名格式:

(参数类型)返回类型

注意:

  • 对于类名(对象名)使用L前缀开头,使用;后缀结尾;
  • 如果是数组类型,使用[前缀开头,使用;后缀结尾;

调用静态方法格式:
QAndroidJniObject 对象名;
对象名<方法返回类型>(包名,方法名,方法签名,方法参数列表)
如果没有参数,则方法签名和方法参数列表可以省略,程序会自动提供正确的签名。

调用非静态方法格式:
QAndroidJniObject 对象名;
对象名(方法名,方法签名,方法参数列表)
如果没有参数,则方法签名和方法参数列表可以省略,程序会自动提供正确的签名。

调用静态类方法格式:
QAndroidJniObject 对象名;
对象名(包名,方法名,方法签名,方法参数列表)
如果没有参数,则方法签名和方法参数列表可以省略,程序会自动提供正确的签名。

调用非静态方法格式:
QAndroidJniObject 对象名;
对象名(方法名,方法签名,方法参数列表)
如果没有参数,则方法签名和方法参数列表可以省略,程序会自动提供正确的签名。

总结:

  • 调用静态类/非类方法时,需要提供完整的包名进行精确匹配。

2.2 方法签名

基本类型:
在这里插入图片描述
对象类型:
在这里插入图片描述
其他:
在这里插入图片描述

2.3 调用示例

QAndroidJniObject类中调用方法:

下面的调用方法中:
“com/hjx/TestJNI”:包名(全限定类名)
“test”:方法名
“()V”:方法签名
<void>:方法返回类型

//获得活动对象
QAndroidJniObject m_activity = QtAndroid::androidActivity();
//调用非静态方法
m_activity.callMethod<void>("test4");
//调用静态方法
m_activity.callStaticMethod<jint>("com/hjx/TestJNI",
                                    "test"
                                    //,"()I"//方法签名可以省略
                                    );
//构造String参数
QAndroidJniObject obj = QAndroidJniObject::fromString("jiangxueHan");
jstring jstr = obj.object<jstring>();
//调用非静态对象方法(返回类型为对象,如String)
m_activity.callObjectMethod("test5",
                                         "(Ljava/lang/String;)Ljava/lang/String;",
                                        jstr);

//调用静态对象方法
 m_activity.callStaticObjectMethod("com/hjx/TestJNI",                                                        
 									"test3",
                    				"(Ljava/lang/String;)Ljava/lang/String;",
                                   jstr);

2.4 注意事项

为了能够调用非静态方法,因为类没有创建时,是无法调用非静态方法的。因为需要对AndroidManifest.xml进行修改,把android:name改为包名,然后该包的方法继承主Activity的类,使得项目已启动就能创建类,这样我们就能调用非静态方法。
在这里插入图片描述
引入AndroidManifest.xml的方法,在项目中,点击Create Templates
在这里插入图片描述

3 完整示例代码

3.1 部分代码

调用的方法
头文件:


#ifdef Q_OS_ANDROID
#include<QAndroidJniEnvironment>
#include<QAndroidJniObject>
#include<QtAndroid>
#endif
#ifdef Q_OS_ANDROID
        QAndroidJniEnvironment env;
       QAndroidJniObject m_activity = QtAndroid::androidActivity();
       //调用静态方法
        qDebug()<< m_activity.callStaticMethod<jint>("com/hjx/TestJNI",
                                    "test"
                                    //,"()V"//方法签名可以省略
                                    );

        jint num = 1;
        qDebug()<<m_activity.callStaticMethod<jint>("com/hjx/TestJNI",
                                         "test2",
                                         "(I)I",
                                         num);

        //调用静态类方法
        QAndroidJniObject obj = QAndroidJniObject::fromString("jiangxueHan");
        jstring jstr = obj.object<jstring>();
        QAndroidJniObject s = m_activity.callStaticObjectMethod("com/hjx/TestJNI",
                                                                "test3",
                                                   "(Ljava/lang/String;)Ljava/lang/String;",
                                                  jstr);

        //调用非静态方法
        QString qstring = s.toString();
        qDebug()<<qstring;

         m_activity.callMethod<void>("test4");

         //调用非静态类方法
        s =  m_activity.callObjectMethod("test5",
                                         "(Ljava/lang/String;)Ljava/lang/String;",
                                        jstr);
        qstring = s.toString();
        qDebug()<<qstring;

        if(env->ExceptionCheck()){
            env->ExceptionDescribe();
            env->ExceptionClear();
        }

#endif

被调用的java方法

package com.hjx;
import org.qtproject.qt5.android.bindings.QtActivity;

import java.lang.String;

public class TestJNI extends org.qtproject.qt5.android.bindings.QtActivity{
    public static int test() {
        System.out.println("Hello world!");
        return 1;
      }

    public static int test2(int num){
        return num + 2;
       }

   public static String test3(String s){
        return (s + ", Hello!");
       }

   public  void test4(){
        System.out.println("21!");
       }

   public  String test5(String s){
        return (s + ", Hi!");
       }


}

3.2 附赠示例

github
码云
csdn下载