您的位置:首页 > 编程语言 > Java开发

NDK之java调用C方法

2015-12-22 10:30 393 查看
在这里NDK通过JNI调用c通常有两种方法,一种就是用javah编译出java的native方法,之后在c实现,另一种就是用RegisterNatives方法进行native方法的注册,再调用。。

鉴于代码好管理和方便查看我就采用第二种方法

一、我先在java端写native方法,再将动态链接库加载到程序中

public class UUIDNDK
{
static
{
System.loadLibrary("UUIDDemo");
}
public native String getUUID();
}


二、在c端先会将native方法放入一个JNINativeMethod映射数组里面

static JNINativeMethod gMethods[] = { { "getUUID", "()Ljava/lang/String;",(void*) getUUID }, };


a.”getUUID”是java端的native方法.

b.”()Ljava/lang/String;”是java端native代码参数和返回值的描述

c.(void *)getUUID就是c端的实现函数.

三、再重写JNI_OnLoad函数,当java端执行System.loadlibrary()时就会执行JNI_OnLoad()函数

jint JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
LOGE("GetEnv failed");
return JNI_ERR;
}
//注册本地方法
if (registerNativeMethods(env, CLASS_PATH_NAME, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) != JNI_TRUE) {
LOGE("ERROR: registerNatives failed");
return JNI_ERR;
}
return JNI_VERSION_1_4;
}
static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = env->FindClass(className);
if (clazz == NULL) {
LOGE("Native registration unable to find class '%s'", className);
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
LOGE("RegisterNatives failed for '%s'", className);
env->DeleteLocalRef(clazz);
return JNI_FALSE;
}
env->DeleteLocalRef(clazz);
return JNI_TRUE;
}


四、而当VM释放该C组件时,则会呼叫JNI_OnUnload()函数来进行善后清除动作

void JNI_OnUnload(JavaVM* vm, void* reserved)
{
LOGI("JNI_OnUnLoad!");
JNIEnv *env;
jclass cls;
clearMemery();//释放程序中申请的内存
if (vm->GetEnv((void **) &env, JNI_VERSION_1_4))
return;
cls = env->FindClass(CLASS_PATH_NAME);
env->UnregisterNatives(cls);
return;
}


五、编写和java native方法对应C端的函数

jstring getUUID(JNIEnv *env, jclass thiz) {
LOGI("getUUID......");
return converchartojstring(env, "");
}


六、完成
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ndk