Android jni中回调java的方法

在上一篇的基础上,添加在C++代码中回调java方法。

代码如下:

Demo.java 中添加callback函数, 打印一条log.

package com.example.scarecrow.dynamicregisterjni;

import android.util.Log;

public class Demo {
public static final String TAG = "Demo"; static {
System.loadLibrary("JniTest");
Log.d(TAG, "dynamic lib loaded");
} public static native String sayHello(); public static void callback(String message) {
Log.d(TAG, message);
}
}

JniTest.cpp 中添加myCallBack方法,在myDynamicJNI中调用,传个字符串回到JAVA。注意:java端的方法是static的话,一定要用GetStaticMethodID和CallStaticVoidMethod。

//
// Created by yuany on 6/5/18.
//
#include <jni.h>
#include "android/log.h"
#include <cassert> #define LOG_TAG "C_TAG"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) //native method
void myCallBack (JNIEnv *env, jclass jobj)
{
LOGD("myCallBack");
jclass clazz; //找到声明native方法的类
clazz = env->FindClass("com/example/scarecrow/dynamicregisterjni/Demo");
if(clazz == NULL){
LOGD("Findclass error");
return;
}
LOGD("Findclass succeed"); //寻找class里面的方法
jmethodID callbackID = env->GetStaticMethodID(clazz, "callback", "(Ljava/lang/String;)V");
if(callbackID==){
LOGD("find callback error");
return;
}
LOGD("find callback "); jstring result = env->NewStringUTF("this is a callback from C++ codes");
//invoke callback method
env->CallStaticVoidMethod(jobj,callbackID, result);
} //native method
jstring myDynamicJNI (JNIEnv *env, jclass jobj)
{
LOGD("myDynamicJNI");
//invoke callback method
myCallBack(env, jobj);
return env->NewStringUTF("This is my first dynamic JNI test");
} /*需要注册的函数列表,放在JNINativeMethod 类型的数组中,
以后如果需要增加函数,只需在这里添加就行了
参数:
1.java代码中用native关键字声明的函数名字符串
2.签名(传进来参数类型和返回值类型的说明)
3.C/C++中对应函数的函数名(地址)
*/
static JNINativeMethod getMethods[] = {
{"sayHello","()Ljava/lang/String;",(void*)myDynamicJNI},
};
//此函数通过调用JNI中 RegisterNatives 方法来注册我们的函数
static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* getMethods,int methodsNum){
LOGD("registerNativeMethods");
jclass clazz;
//找到声明native方法的类
clazz = env->FindClass(className);
if(clazz == NULL){
return JNI_FALSE;
}
LOGD("after Findclass");
//注册函数 参数:java类 所要注册的函数数组 注册函数的个数
if(env->RegisterNatives(clazz,getMethods,methodsNum) < ){
return JNI_FALSE;
}
LOGD("after RegisterNatives");
return JNI_TRUE;
} //回调函数 在这里面注册函数
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){ LOGD("JNI_OnLoad");
JNIEnv* env = NULL;
//判断虚拟机状态是否有问题
if(vm->GetEnv((void**)&env,JNI_VERSION_1_6)!= JNI_OK){
return -;
}
assert(env != NULL);
//指定类的路径,通过FindClass 方法来找到对应的类
const char* className = "com/example/scarecrow/dynamicregisterjni/Demo";
//开始注册函数 registerNatives -》registerNativeMethods -》env->RegisterNatives
if(!registerNativeMethods(env,className,getMethods, )){
return -;
}
//返回jni 的版本
return JNI_VERSION_1_6;
}

关于JNI更多详细内容可以参考https://blog.csdn.net/rainteen/article/details/43376337#t0

上一篇:Codeforces Round #294 (Div. 2)


下一篇:jpa 原生查询createNativeQuery里面有冒号保留字关键字的问题