1.native层调用java层static方法
//java层定义方法
public native static void request();
//native层执行完request后回调此方法
public static void nativeCallBack() {
System.out.println("nativeCallBack");
//native层实现
JNIEXPORT void JNICALL Java_com_hd_jni_JNITest_request(JNIEnv *env, jclass jclass1) {
//调java方法
jmethodID methodid = (*env)->GetStaticMethodID(env, jclass1, "nativeCallBack", "()V");
(*env)->CallStaticVoidMethod(env, jclass1, methodid, NULL);
}
//测试代码
private void testCallback() {
JNITest.request();
}
2.native层修改java层对象成员变量值,包括直接修改成员变量和调用成员方法修改
//java层定义
public native static void modifyValue(Student student);
//native层实现
JNIEXPORT void JNICALL Java_com_hd_jni_JNITest_modifyValue
(JNIEnv *env, jclass jclass1, jobject obj) {
//根据传入的对象获得对应的class
jclass objClass = (*env)->GetObjectClass(env, obj);
//修改名字
jfieldID nameid = (*env)->GetFieldID(env, objClass, "name", "Ljava/lang/String;");
if (nameid == NULL) {
return;
}
jstring nameStr = (jstring) (*env)->GetObjectField(env, obj, nameid);
const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL);
(*env)->ReleaseStringUTFChars(env, nameStr, name);
nameStr = (*env)->NewStringUTF(env, "name has modify");
if (nameStr == NULL) {
return;
}
(*env)->SetObjectField(env, obj, nameid, nameStr);
//修改性别
jmethodID sexMethodid = (*env)->GetMethodID(env, objClass, "setSex", "(I)V");
(*env)->CallVoidMethod(env, obj, sexMethodid, 2);
}
//测试代码
private void testModifyValue() {
Student student = new Student("lisi", 0);
JNITest.modifyValue(student);
Toast.makeText(JNITestActivity.this, "name=" + student.name + ",sex=" + student.sex, Toast.LENGTH_LONG).show();
}
3.自定义native方法名
1)定义方法结构体
// 结构体,分别是java层的函数名称,签名,对应的函数指针
static JNINativeMethod gMethods[] = {
{"testChangeString", "(Ljava/lang/String;)Ljava/lang/String;", (void *) testChangeString},
};
2)自己实现JNI_OnLoad,写在任何一个.c文件都可以
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
jint result = -1;
if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
/*
* 如果要注册,需要两步,
* 首先FindClass,
* 然后RegisterNatives
*/
char className[20] = {"com/hd/jni/JNITest"};
jclass clazz = (*env)->FindClass(env, (const char *) className);
if ((*env)->RegisterNatives(env, clazz, gMethods, sizeof(gMethods) / sizeof(gMethods[0])) !=
JNI_OK) {
printf("register native method failed!\n");
return -1;
}
//一定要返回版本号,否则会出错。
result = JNI_VERSION_1_4;
return result;
}