android JNI 系列 三

主题:

● 获取Java类

● 访问Java属性

●访问Java方法

●创建Java对象

●抛异常

 

1. 获取Java类

    方法一:

    jclass clazz = env->GetObjectClass(thisObj);

    方法二:

    jclass cls = env->FindClass("com/lht/JNITest");

以上方法是先获取到Class对象,当然这是c++的写法,c的写法是不一定的,我是喜欢用c++的方式来实现JNI

 

2. 读写Java属性

以后是用到的JNI 函数

    jfieldID    (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);

    jobject     (*GetObjectField)(JNIEnv*, jobject, jfieldID);
    jboolean    (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
    jbyte       (*GetByteField)(JNIEnv*, jobject, jfieldID);
    jchar       (*GetCharField)(JNIEnv*, jobject, jfieldID);
    jshort      (*GetShortField)(JNIEnv*, jobject, jfieldID);
    jint        (*GetIntField)(JNIEnv*, jobject, jfieldID);
    jlong       (*GetLongField)(JNIEnv*, jobject, jfieldID);
    jfloat      (*GetFloatField)(JNIEnv*, jobject, jfieldID);
    jdouble     (*GetDoubleField)(JNIEnv*, jobject, jfieldID);

    void        (*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
    void        (*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
    void        (*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
    void        (*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
    void        (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
    void        (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
    void        (*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
    void        (*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
    void        (*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);

我们先看一下

jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);//这个方法相当的耗时,请不要频繁的使用,当读到以后应该保存起来

JNIEnv*就不用说了,jclass是要访问属性的类的class对象,如何获取已在上一节讲述了,第三个参数为属性名称,如你定义了一个String mName;那么参数为"mName",

第四个参数是属性的签名,mName的类型为String,那么它的签名应该是指"Ljava/lang/String;"

所以我们代码写成:jfieldID nameId = env->GetFieldID(class, "mName", "Ljava/lang/String;")

拿到nameId我们再来看看

jString name = (jString)env->GetObjectField(jObj, nameId);

jObj是java调用传入的this对象。

如果属性域是静态的,那么方法为GetStaticFieldID, GetStaticObjectField

获取完了以后,我们要设置呢?

env->SetObjectField(jObj, nameId, name); //第三个参数为值

 

3. 访问Java方法

根读写java属性的步骤一致。

先获取方法的ID

jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)

jclass, 就是要访问的类的类对象,是需要根据本篇的第一节的描述获取的jclass对象

name, 方法名称

sig, 方法的签名,如:“(Ljava/lang/String;I)V”

CallVoidMethod(jclass clazz,, methodID, ...);

CallVoidMethod(jclass clazz,, methodID, jvalue args[]);

CallVoidMethod(jclass clazz,, methodID, va_list args);

... ,  用来传递参数,这个相信在Java中用的比较的多,如println类,你可以在后面跟很多个参数,如jString,jint and so on.

jvalue是一个枚举类:

typedef union jvalue {
    jboolean    z;
    jbyte       b;
    jchar       c;
    jshort      s;
    jint        i;
    jlong       j;
    jfloat      f;
    jdouble     d;
    jobject     l;
} jvalue;

va_list,是c语言中用来解决变参的宏,

后面两个调用方法不用管,一般我们用第一个就够了。

调用静态的方法:

跟上面的没有什么区别,只是分别用GetStaticMethodID和CallStaticVoidMethod方法

CallStaticObjectMethod(class, methodid, env->newStringUTF("java.class.path"))

 

4. 在JNI中创建Java类对象

jobject NewObject(jclass clazz, jmethodID methodID, ...)

参数说明:

clazz, java类

jmethodID, 构造函数ID

..., 构造参数

 

5. 抛异常

有两个接口可以实现

jint        (*Throw)(JNIEnv*, jthrowable);
jint        (*ThrowNew)(JNIEnv *, jclass, const char *);

 

6. 创建Java虚拟机

在非JNI的代码中,我们可以通过创建一个Java虚拟机来访问Java类

JavaVMOption options[1];

JavaVMInitArgs vm_args;

JavaVM *jvm;

JNIEnv *env;

 

options[0].optionString = "-Djava.class.path=.";

memset(&vm_args, 0, sizeof(vm_args));

vm_args.version = JNI_VERSION_1_4;

vm_args.nOption = 1;

vm_args.options = options;

JNI_CreateJavaVM(&jvm, (void**) & env, &vm_args);

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您好!关于在Android开发中使用SWIG生成JNI代码的问题,我可以给您一些指导。 SWIG(Simplified Wrapper and Interface Generator)是一个工具,可以用于将C/C++代码包装成其他编程语言(如Java)的接口。在Android开发中,您可以使用SWIG来生成JNI(Java Native Interface)代码,以便在Java和C/C++之间进行交互。 下面是一些基本的步骤来使用SWIG生成JNI代码: 1. 安装SWIG:首先,您需要安装SWIG工具。您可以从SWIG的官方网站(http://www.swig.org)下载适合您操作系统的版本,并按照安装指南进行安装。 2. 编写SWIG接口文件:创建一个名为`example.i`的SWIG接口文件,并在其中定义您要包装的C/C++代码的接口。例如,如果您要包装一个名为`example.h`的头文件中的函数和结构体,您可以在接口文件中使用类似以下的代码: ``` %module example %{ #include "example.h" %} %include "example.h" ``` 3. 生成JNI代码:使用以下命令来生成JNI代码: ``` swig -java example.i ``` 该命令将生成一系列JNI源文件和一个Java类文件,用于在Java中访问C/C++代码。 4. 将生成的文件添加到Android项目:将生成的JNI源文件(通常是`.c`和`.h`文件)添加到您的Android项目的`jni`目录中。确保您的项目已正确配置NDK构建系统。 5. 在Java中使用JNI代码:在Java类中,您可以使用生成的Java类文件中的JNI包装器来访问C/C++代码。例如,您可以使用`System.loadLibrary("example")`来加载生成的JNI库,并使用JNI函数来调用C/C++函数。 这是一个简单的概述,描述了如何使用SWIG生成JNI代码。请注意,SWIG提供了许多高级功能和选项,可以根据需求进行配置和定制。 希望这些信息对您有帮助!如果您有任何其他问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值