【Tech-Android-Jni】Jni的基本方法(1)

1.生成头文件
首先通过编写本地函数native的方法,利用javah 指令生成C的头文件。一般的头文件会给出所已经定义好的方法。
例如下列:
JNIEXPORT void JNICALL Java_com_example_adder_actNative_nativeExec(JNIEnv *, jclass);(头文件)
这里就包含了一个actNative类中的一个返回值为空的nativeExec的方法。

2.根据这个方法定义可以写出c的文件。

JNIEXPORT void JNICALL Java_com_example_adder_actNative_nativeExec
  (JNIEnv *env, jclass thiz){
      第一个参数为这个c文件的指针,第二个参数是呼叫C函数的Java层的对象(是一个reference).
      可以根据:
      jclass clazz = (*env)->GetObjectClass(env thiz);(该方法获取java层的对象) 称之喂类别指针。 
      //由于thiz只是一个参考对象类别,该对象类别在该方法结束的时候会给删除掉,所以要将其转为全局参考变量
       m_jclass = (jclass)(*env)->NewGlobalRef(env,clazz );

      //同理可以得到thiz参考类的全局变量
      m_jobject = (jobject)(*env)->NewGlobalRef(env,thiz);
     //同理可以得到该参考类别的字段名,并将其存入C函数中
      m_fid  = (*env)->GetFieldID(env,clazz,"numb","I");//注意 这里利用的是clazz ,就是java层的reference.非全局参考变量。
     //再获得java层中的函数方法
     m_rv_mid = (*env)->GetMethodID(env,m_jclass ,"setV","(I)V");//注意 这里利用的是全局参考变量。m_jclass.
    //如果java层中的的setV()方法是静态的话,则利用GetStaticMethodId()方法。

     //获取一个字段中的值 例如一个整形n
     n = (int)(*env)->GetObjectField(env,m_object,m_mid);
     //m_mid为已经在java层获取过来的字段ID,通过getFieldID的方法获取。

3.在C函数中如何调用java层的方法呢?
(*env)->CallVoidMethod(env,m_jobject,m_mid,sum);
m_jobject代表了正指向java层目前对象的的关联全局参考。m_mid储存了方法名的ID,sum是要给方法 函数存入值。
如果方法是一个静态的话,利用 CallStaticViodMethod();

总结:
1.获取java中的字段ID,方法ID并存入C函数中的话,要利用clazz,通过GetObjectClass(),获取类别指针。
2.获取字段中的值,或调用Java层的方法时候,利用m_jobject,通过NewGlobalRef(env,thiz)获取。

以上为入门JNI的一些总结,对C不是很熟悉,我知道一定有错,但会一直学习下去。边学边改正,也 望指出。

你可能感兴趣的:(【Tech-Android-Jni】Jni的基本方法(1))