android jni的坑

传统的jni方式是这个步骤

1.在java文件中定义native函数

2.使用javah 生成对应C函数定义并实现

3.编写Android.mk把C源码用ndk编译成动态库

4.在java中调入编译好的动态库

然而android下是不行的,android下的jni必须要有JNI_OnLoad函数

#define JNIREG_CLASS "com/hello/helloworld"//指定要注册的类

#define TAG "HELLOWORLD-JNI"

static JNINativeMethod gMethods[] = {
    { "hello_world", "([BJ[BJ)[B", (void*)Java_com_hello_hello_world },//绑定
};

static int registerNativeMethods(JNIEnv* env, const char* className,
        JNINativeMethod* gMethods, int numMethods)
{
    jclass clazz;
    clazz = (*env)->FindClass(env, className);
    if (clazz == NULL) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "Native registration unable to find class '%s'\n", className);
        return JNI_FALSE;
    }
    if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "RegisterNatives failed for '%s'\n", className);
        return JNI_FALSE;
    }

    return JNI_TRUE;
}


static int registerNatives(JNIEnv* env)
{
    if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, 
                sizeof(gMethods) / sizeof(gMethods[0])))
        return JNI_FALSE;

    __android_log_print(ANDROID_LOG_INFO, TAG, "Load success!");
    return JNI_TRUE;
}

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1;

    if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv failed!");
        return -1;
    }
    if(env == NULL){
        __android_log_print(ANDROID_LOG_ERROR, TAG, "GetEnv failed!");
        return -1;
    }

    __android_log_print(ANDROID_LOG_INFO, TAG, "Loading . . .");

    if (!registerNatives(env)) {//注册
        return -1;
    }
    /* success -- return valid version number */
    result = JNI_VERSION_1_4;

    return result;
}

关于JNINativeMethod的说明,这篇文章写的很清楚

[Android JNI 使用的数据结构JNINativeMethod详解]http://blog.csdn.net/bigapple88/article/details/6756204

参考文章:

Android JNI(实现自己的JNI_OnLoad函数)

Android的NDK开发(1)————Android JNI简介与调用流程

可能会遇到的陷阱(其中的内存释放问题我就遇到了):

Android NDK之JNI陷阱