JNI中的C回调java中的方法

C反射调用java方法,反射机制和java中的反射机制差不多。

以下是调用一个返回值为空,参数为空的实例

#include
#include
#include

#include
//#define LOG_TAG "System.out"
#define LOG_TAG "lalalal"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

/*
javap -s 包名.类名
使用是使用
    LOGI("info\n");
    LOGD("debug\n");
*/

JNIEXPORT void JNICALL Java_com_example_zhongtao_jniday14_JNI_callVoid(JNIEnv *env, jobject thiz){
      //1.获取字节码 (env,要找到的字节码对应的路径)
      //2.获取方法
      //3.创建对象
      //4.通过对象调用方法

       //调用的这个方法返回值是空,方法的参数也是空值
      //找到字节码 第一个参数env 第二个参数要找的类的路径 包名.类名
      jclass clazz=(*env)->FindClass(env,"com/example/zhongtao/jniday14/JNI");
      LOGD("运行在C中。。。。。");
      //获取方法找到方法的ID   第一个参数env 第二个参数调用的对象, 第三个参数 调用的方法的名字 第四个参数被调用的方法的签名(该签名可以使用javap -s 类名查看)

      //方法签名 void是V int是I String类型则需要写全(Ljava/lang/String;)V 前面必须加个L 
      jmethodID jmethodid=(*env)->GetMethodID(env,clazz,"helloFromJava","()V");
      //如果native方法和要回调的java方法在同一个java类中就不用创建对象,直接使用,例如该例子的native方法和要调用的方法都在JNI类中,直接使用jobject作为对象
      //第一个参数env 第二个参数要调用的对象 第三个参数要调用方法的对象, 后面的参数是可变参数 调用方法时有参数就是被调用的方法的参数,
      (*env)->CallVoidMethod(env,thiz,jmethodid);
}


JNIEXPORT void JNICALL Java_com_example_zhongtao_jniday14_JNI_callInt(JNIEnv *env, jobject thiz){
    //1.获取字节码
    jclass clazz=(*env)->FindClass(env,"com/example/zhongtao/jniday14/JNI");
    LOGD("运行在C中。。。。。");
    //2.获取方法
    jmethodID jmethodid=(*env)->GetMethodID(env,clazz,"add","(II)I");
    //3.创建对象4.通过对象调用方法
    //传递两个参数到被调用的JAVA程序中
    int result=(*env)->CallIntMethod(env,thiz,jmethodid,3,4);
    LOGD("result=%d",result);
}


JNIEXPORT void JNICALL Java_com_example_zhongtao_jniday14_JNI_callString(JNIEnv *env, jobject thiz){
//1.获取字节码
    jclass clazz=(*env)->FindClass(env,"com/example/zhongtao/jniday14/JNI");
    LOGD("运行在C中。。。。。");
    //2.获取方法
    jmethodID jmethodid=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V");
    jstring jstr=(*env)->NewStringUTF(env,"hello");
    //3.创建对象4.通过对象调用方法
    //传递两个参数到被调用的JAVA程序中
    (*env)->CallVoidMethod(env,thiz,jmethodid,jstr);
}
native中的方法

public class JNI {
    static {
        System.loadLibrary("hello");
    }
    //空的方法
    public void helloFromJava() {
        System.out.println("空方法");
    }
    //传int类型参数的方法
    public int add(int x, int y) {
        return x+y;
    }
    //
    public void printString(String s) {
       System.out.println("s==="+s);
 }

   //调用helloFromJava
    public native void callVoid();
    //调用add
    public native void callInt();
    //调用printString
    public native void callString();  
}

Activity中的方法

public class MainActivity extends AppCompatActivity {
    private JNI jni;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jni = new JNI();
    }

    //调用helloFromJava
    public void callVoid(View view) {
        jni.callVoid();
    }

    //调用add
    public void callInt(View view) {
        jni.callInt();
    }

    //调用printString
    public void callString(View view) {
        jni.callString();
    }
}


你可能感兴趣的:(JNI)