在Android开发本地代码时,有两种方式。一种是使用javah生成头文件。然后编辑源码,还有一种不用生成头文件,直接编辑代码后,使用RegisterNatives方法进行注冊,以下是一个Demo:
Java代码:
package com.example.jnitest;
public class TestJni {
static {
System.loadLibrary("Hello");
}
// static method
public static native String test();
// member method
public native String test2();
}
这里定义了两个native方法,test是静态方法,test2是成员方法。
使用C++实现两个方法:
static jstring test(JNIEnv *env, jclass clz)
{
LOGD("Hello1");
return env->NewStringUTF("Hello1");
}
static jstring test2(JNIEnv *env, jobject obj)
{
LOGD("Hello2");
return env->NewStringUTF("Hello2");
}
实现了之后,须要注冊两个方法
第一步:定义数据结构:
// register methods:
static JNINativeMethod methods[] = {
{"test", "()Ljava/lang/String;", (void*) &test},
{"test2", "()Ljava/lang/String;", (void*) &test2}
};
第二步:在JNI_OnLoad方法中,对方法进行注冊:
int jniRegisterNativeMethods(JNIEnv* env,
const char* className,
const JNINativeMethod* gMethods,
int numMethods)
{
jclass clazz;
int tmp;
LOGD("Registering %s natives\n", className);
clazz = env->FindClass(className);
if (clazz == NULL) {
LOGD("Native registration unable to find class '%s'\n", className);
return -1;
}
if ((tmp=env->RegisterNatives(clazz, gMethods, numMethods)) < 0) {
LOGD("RegisterNatives failed for '%s', %d\n", className, tmp);
return -1;
}
return 0;
}
int registerNativeMethods(JNIEnv *env) {
return jniRegisterNativeMethods(env, "com/example/jnitest/TestJni", methods, sizeof(methods) / sizeof(methods[0]));
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
JNIEnv* env = NULL;
jint result = JNI_ERR;
if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return result;
}
if (registerNativeMethods(env) != JNI_OK) {
return -1;
}
result = JNI_VERSION_1_4;
LOGD("jni load start: %d", result);
return result;
}
Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -D__STDC_CONSTANT_MACROS
LOCAL_LDLIBS += -lc -lm -llog
LOCAL_SHARED_LIBRARIES += liblog libcutils libnativehelper
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := com_example_jnitest_TestJni.cpp
include $(BUILD_SHARED_LIBRARY)