您的位置:首页 > 移动开发 > Android开发

Android JNI实例代码(一)

2012-07-18 15:41 267 查看
前几天有关Android JNI开发系列教程中有关的源代码,可以在本文中查找:

一、 在JNI中执行Java方法

[java] view
plaincopy

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代码:

[cpp] view
plaincopy

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类型的属性读写

[java] view
plaincopy

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层代码:

[cpp] view
plaincopy

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关键字

[java] view
plaincopy

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");  

 }  

}  

下面是JNI层代码:

[cpp] view
plaincopy

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是静态的。  

}  

给出了较完整的JNI下执行Java的源代码第一部分,有关第二部分可以查看 Android JNI实力代码(二)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  jni android java null string j2se