java 接口定义:
java
public interface Callback {
void onResult(int status, String message);
}
java 设置回调:
java
public class Sample {
static {
System.loadLibrary("sample_core_jni");
}
public static native int process(long handle, String message);
public static void onCallback(int status, String message) {
if (mCallback != null) {
mCallback.onResult(status, message);
}
}
private static Callback mCallback;
public static void setCallback(Callback callback) {
if (callback == null) {
throw new NullPointerException("callback can not be null");
}
mCallback = callback;
}
// 添加其他native函数
....
}
JNI 注册回调函数:
cpp
#include <jni.h>
#include <iostream>
// 全局引用,确保JNI环境可以访问
JavaVM *g_VM;
jclass gCallbackClassSample = nullptr;
jmethodID gOnCallbackMethodID = nullptr;
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = nullptr;
jint result = -1;
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return result;
}
//JavaVM是虚拟机在JNI中的表示,等下再其他线程回调java层需要用到
env->GetJavaVM(&g_VM);
register_fields(env);
LOGI("JNI OnLoad result : %d", result);
return JNI_VERSION_1_6;
}
register_fields(JNIEnv *env) {
//注册Java回调函数所在的类及回调函数
}
int ChatCallback(int status, const char *output) {
JNIEnv *env;
bool mNeedDetach = false;
//获取当前native线程是否有没有被附加到jvm环境中
int getEnvStat = (*g_VM).GetEnv( (void **)&env, JNI_VERSION_1_6);
if (getEnvStat == JNI_EDETACHED) {
//如果没有, 主动附加到jvm环境中,获取到env
if (g_VM->AttachCurrentThread(&env, NULL) != JNI_OK) {
LOGE("ChatCallback failed to attach current thread");
}
mNeedDetach = JNI_TRUE;
}
jString j_out = native_message_to_java_message(env, output);
if (fields.chat_result_callback != nullptr) {
env->CallStaticVoidMethod(gCallbackClassSample, gOnCallbackMethodID, (int)status, j_out);
}
//释放当前线程
if(mNeedDetach) {
g_VM->DetachCurrentThread();
}
env = NULL;
return 0;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_yourapp_process(JNIEnv *env, jlong handle, jString message) {
//
const char* c_message = ...
//该函数为异步函数
int err = Chat(handle, c_message, ChatCallback);
}