JNI调用java函数
以下以静态方法为例
在app端创建回调方法
同上个例子 在com.example.helloso.MainActivity中
创建一个静态回调函数
public static void Callback_GetString(){ Toast.makeText(mContext,"Callback_GetString",Toast.LENGTH_SHORT); Log.i(TAG,"Callback_GetString"); }
在so代码中调用回调
在c++函数中调用回调函数
//该函数同上一节对应java native函数 com.example.helloso.MainActivity中HelloWorld() jstring Java_com_example_helloso_MainActivity_HelloWorld(JNIEnv* env, jobject thiz) { LOGE("Start HelloWorld"); Callback_TestVoid(); LOGE("End HelloWorld"); return env->NewStringUTF("Java_com_example_helloso_MainActivity_HelloWorld"); }
重写JNI_Onload函数 在载入时加载确定jni回调函数的ID
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { LOGI("Start JNI_OnLoad"); JNIEnv* env; g_pJavaVM = vm; if (vm->GetEnv((void**)&env, JNI_VERSION_1_6) != JNI_OK) { return JNI_ERR; // JNI version not supported. } jclass clz = env->FindClass( "com/example/helloso/Callback"); g_jniHelperClz = (jclass)env->NewGlobalRef(clz); jmethodID jniHelperCtor = env->GetMethodID(g_jniHelperClz, "<init>", "()V"); jobject handler = env->NewObject(g_jniHelperClz, jniHelperCtor); g_jniHelperObj = env->NewGlobalRef(handler); / g_methodTestVoid = env->GetStaticMethodID(g_jniHelperClz, "Callback_TestVoid", "()V"); g_methodTestString = env->GetStaticMethodID(g_jniHelperClz, "Callback_TestString", "(Ljava/lang/String;)Ljava/lang/String;"); g_methodTestByteArray = env->GetStaticMethodID(g_jniHelperClz, "Callback_TestByteArray", "([BI)[B"); /// g_mainActivityObj = NULL; LOGI("End JNI_OnLoad"); return JNI_VERSION_1_6; }
回调函数调用,先获得env,再通过全局jmethodID 调用java函数
void Callback_TestVoid() { LOGE("Star t Callback_TestVoid"); JNIEnv *env; jint res = g_pJavaVM->GetEnv((void**)&env, JNI_VERSION_1_6); if (g_methodTestVoid != NULL) { LOGE("Start CallStaticVoidMethod"); env->CallStaticVoidMethod(g_jniHelperClz, g_methodTestVoid); } LOGE("End Callback_TestVoid"); }
解释GetMethodID 获得函数地址
jmethodID GetMethodID(jclass clazz, const char* name, const char* sig);//获得函数地址 jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig);//获得静态函数地址
sig表示标识函数格式
sig参数示意:
boolean:Z
byte:B
char:C
short:S
int:I
long:J
float:F
double:D
void:V
[数组]:[+类型
Object对象:L包名/类名; 或包名/类名$标识嵌套类;
例子(方法 ->- 对应的sig):
void M1(int A,int B) ->- “(II)V”
void M2(String S) ->- “(Ljava/lang/String;)V”
void M3(int[] I) ->- “([I)V”
String M4(String S) ->-"(Ljava/lang/String;)Ljava/lang/String"
long M5(int I,Class class) ->- “(ILjava/lang/Class;)J”
void M6(long LONG) ->- “(J)V”
番外 JNI java string到c/c++相关
Android Native 开发之 NewString 与 NewStringUtf 解析
Android jni/ndk编程二:jni数据类型转换(primitive,String,array)
jni直接转byte_JNI jbyteArray转char*
String (UTF-16) | [java] | -------------------- JNI 调用 [cpp] | v jstring (UTF-16) | +--------------------------+---------------------------+ |GetStringChars/NewString |GetStringUTFChars/NewStringUTF | | v v wchar_t* char* (UTF_16) (UTF-8)