Android JNI实例代码(一)

来源:互联网 发布:sqrt在c语言中意思 编辑:程序博客网 时间:2024/06/11 09:32

Android JNI实例代码(一) 一、 在JNI中执行Java方法 class AndroidJniDemo { private native void executeMethod(); private void show() { System.out.println("Java cwj print"); //执行了show方法后打印java层的输出 } public static void main(String args[]) { //这里我们在J2SE中测试,Android开发者可以放到Activity中的onCreate调用 AndroidJniDemo ajd = new AndroidJniDemo(); ajd.executeMethod(); } static { System.loadLibrary("AndroidJniDemo"); } } 下面是JNI代码: JNIEXPORT void JNICALL Java_AndroidJniDemo_executeMethod(JNIEnv *env, jobject obj) { jclass clazz = (*env)->GetObjectClass(env, obj); //通过类的对象 jmethodID mid = (*env)->GetMethodID(env, clazz, "show", "()V"); //查找java中的show方法的ID,最后的签名符号为void类型 if (mid == NULL) { return; //如果方法ID没有找到 } printf("JNI cwj print"); //从JNI中打印输出 (*env)->CallVoidMethod(env, obj, mid); //执行show方法 } 二、获取/设置类的域或者说属性字段 (1 String类型的属性读写 class AndroidJniDemo2 { private String sTmp; private native void readwriteField(); public static void main(String args[]) { AndroidJniDemo2 ajd2 = new AndroidJniDemo2(); ajd2.sTmp = "cwj"; ajd2.readwriteField(); System.out.println("Java cwj print ="+ajd2.sTmp); //java层打印结果 } static { System.loadLibrary("AndroidJniDemo2"); } } 下面是JNI层代码: JNIEXPORT void JNICALL Java_AndroidJniDemo2_readwriteField(JNIEnv *env, jobject obj) { jfieldID fid; jstring jstr; const char *szTemp; jclass clazz = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, clazz, "sTmp", "Ljava/lang/String;"); // 注意sTmp是Java中声明的,String类型在java.lang.String包中,签名符号的格式注意 if (fid == NULL) { return; } jstr = (*env)->GetObjectField(env, obj, fid); //Java的String类型,要用GetObjectField函数获取,这里Android123提示大家没有GetStringField这样的函数在JNI中,或者说在C语言中 szTemp = (*env)->GetStringUTFChars(env, jstr, NULL); //因为还需要赋值,在C中我们转换为utf8的类型。 if (szTemp == NULL) { return; } printf("JNI cwj print=%s", szTemp); //先打印Java层传进来的值 (*env)->ReleaseStringUTFChars(env, jstr, szTemp); //szTemp打印完不用了要及时释放掉 jstr = (*env)->NewStringUTF(env, "android123"); //返新的字段值,供Java层打印 if (jstr == NULL) { return; } (*env)->SetObjectField(env, obj, fid, jstr); //设置新的属性值。 } (2 int或double类似的类型的属性读写,本例同时属性值是一个静态的定义,注意下面加粗的static关键字 class AndroidJniDemo3 { private static int sAge; private native void readwriteField(); public static void main(String args[]) { AndroidJniDemo3 ajd3 = new AndroidJniDemo3(); AndroidJniDemo3.sAge = 23; ajd3.readwriteField(); //执行jni层 System.out.println("Java cwj print="+sAge); //java层打印新的值,应该为120 } static { System.loadLibrary("AndroidJniDemo3"); } } JNIEXPORT void JNICALL Java_AndroidJniDemo3_readwriteField(JNIEnv *env, jobject obj) { jfieldID fid; jint nTemp; jclass clazz = (*env)->GetObjectClass(env, obj); fid = (*env)->GetStaticFieldID(env, clazz, "sAge", "I"); //因为是整形,这里签名符号为I,注意使用的函数中包含Static代表是一个静态的属性 if (fid == NULL) { return; } nTemp = (*env)->GetStaticIntField(env, clazz, fid); printf("JNI cwj print=%d", nTemp); //这里应该显示23 (*env)->SetStaticIntField(env, clazz, fid, 120); //设置新的值为120,注意包含了Static,java层中定义的sAge是静态的。 }