江苏 无锡 缪小东
本篇主要介绍如何在JNI中,构造一个java对象。通过本章的学习大家会发现构造java对象基本和调用java对象的方法一致。
下面是一个包含创建某个对象的本地方法。
public class ConstructorAccess{
public static native void callThread(); //创建java对象的本地方法
public static void main(String[] args){
ConstructorAccess.callThread(); //调用本地方法
}
}
class ThreadTest implements Runnable { //辅助的线程
int i = 0 ; //局部变量
public void run(){
try{
Thread.sleep(2000); //线程休息
}catch(Exception e){
System.out.println("Error !");
}
System.out.println("This is the "+(i++) + "th's sleep"); //打印线程休息的次数
}
}
下面就是包含构造某个线程对象的本地方法。
#include <jni.h>
JNIEXPORT void JNICALL Java_ConstructorAccess_callThread(JNIEnv *env, jclass cls){
jclass jcls , threadcls; //ThreadTest和Thread类的类
jmethodID mid , mid2 , startmid ;
//ThreadTest和Thread类的构造方法和Thread实例的开始方法
jobject obj , obj2 ; //ThreadTest和Thread类的实例
jcls = (*env)->FindClass(env, "ThreadTest"); //得到ThreadTest类的类
if (jcls == NULL) { return ; }
mid = (*env)->GetMethodID(env, jcls,"<init>", "()V"); //构造ThreadTest类
//在JNI中,构造器其实就是一个名称为"<init>"的方法
//返回值为void
if (mid == NULL) { return ; }
obj = (*env)->NewObject(env, jcls, mid, NULL); //创建该类的实例
threadcls = (*env)->FindClass(env, "Ljava/lang/Thread;"); ////得到Thread类的类
if (threadcls == NULL) { return ; }
mid2 = (*env)->GetMethodID(env, threadcls,"<init>", "(Ljava/lang/Runnable;)V");
//达到构造器的方法
if (mid2 == NULL) { return ; }
obj2 = (*env)->NewObject(env, threadcls, mid2, obj); //以刚才创建的ThreadTest对象
//为参数,使用Thread类的new Thread(Runnable r)创建类
startmid = (*env)->GetMethodID(env, threadcls,"start", "()V"); //得到线程类的启动方法
if (startmid == NULL) { return ; }
(*env)->CallVoidMethod(env, obj2, startmid); //调用start方法启动线程
(*env)->DeleteLocalRef(env, jcls); //释放资源
}
在上面我们分析了JNI如何操作java对象的属性、方法和构造方法!这些java对象可以是在JNI本地代码中创建的,也可以是通过JNI本地方法的参数传入的!传入的这么做啊!请仔细看看本地方法在.h文件中的表示,第二个参数就可以了!(明白了吧!不明白多看几遍哦!同时还要看Signature)。
这三篇我们讲述了在JNI中操作Java对象。下篇将讲述如何在JNI中处理异常。
联系客服