#include <jni.h> #include <android/log.h> #include <string.h> #ifndef _Included_com_jni_MethodCall #define _Included_com_jni_MethodCall #ifdef __cplusplus extern "C" { #endif JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallMethod1(JNIEnv *, jobject); JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallMethod2(JNIEnv *, jobject); JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallStaticMethod(JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallMethod1(JNIEnv * env, jobject obj) { jmethodID mid; // 方法标识id jclass cls = env->GetObjectClass(obj); // 类的对象实例 mid = env->GetMethodID(cls, "javaMethod1", "()V"); env->CallVoidMethod(obj, mid); return env->NewStringUTF("jniCallMethod1"); } JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallMethod2(JNIEnv * env, jobject obj) { jmethodID mid; // 方法标识id jclass cls = env->GetObjectClass(obj); // 类的对象实例 mid = env->GetMethodID(cls, "javaMethod2", "()Ljava/lang/String;"); jstring js = (jstring) env->CallObjectMethod(obj, mid); return js; } JNIEXPORT jstring JNICALL Java_com_jni_MethodCall_jniCallStaticMethod( JNIEnv * env, jobject obj) { jmethodID mid; // 方法标识id jclass cls = env->GetObjectClass(obj); // 类的对象实例 mid = env->GetStaticMethodID(cls, "javaStaticMethod", "(Ljava/lang/String;)V"); jstring input = env->NewStringUTF("jniCallStaticMethod->>javaStaticMethod"); env->CallStaticVoidMethod(cls, mid, input); return env->NewStringUTF("jniCallStaticMethod"); }
该cpp文件中有3个方法(我这里把方法名都写得很明白直观,相信不需要注释都知道是调用的哪一个java方法)
我们知道,在java编程中,对一个类的调用,其实是先创建一个类的对象实例,然后再调用它的方法(这里指的是非static方法) ,那么我们是如何在c/c++文件中调用java方法的呢?
回到上面的HelloWorld,我们讲方法名的时候,下边有随便提到的方法的参数,其中,第二个参数obj其实就是我们在java中使用的类的实例,到这里,相信是如何调用java方法的大家都明白了吧;
在java中,每一个方法其实都有一个id,我们在c/c++中不能直接通过obj来调用一个java方法,我们要先获取方法的id,通过GetMethodID()来获取,需要传入类的类型,方法名,方法的签名(方法签名在文章后面会讲到签名规则);然后再在线程里面调用java方法,通过env->Call****Method();需要传入对象实例,方法id,或者其它参数;(上面只展示了几个这种方法,其它的方法如果大家有需要用到可以自行查找资料解决);
3.编写Android.mk文件,在Android.mk文件后面添加如下内容
include $(CLEAR_VARS) LOCAL_MODULE := methodcall LOCAL_SRC_FILES := methodcall.cpp include $(BUILD_SHARED_LIBRARY)
4.执行ndk-build 命令,下面是分别执行3个jniCall****方法的结果
三、jni调用Java类的方法(1)
上面是c++调用java方法的例子,下面再帖一个c调用java方法的例子
1.Java文件 MethodCall1.java
package com.jni; public class MethodCall1 { static { System.loadLibrary("methodcall1"); } public static int value = 0; public static void javaMethod() { value = 12; } public native int jniCalljavaMethod(); }
2.methodcall.c