Overview
###创建一个Java类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.example.hellojni;
public class Test {
public native void callC();
public void print(String msg){
System.out.println(msg);
}
public int add(int x, int y){
return x + y;
}
}
###生成头文件
进入project/bin/classes目录,执行javah com.example.hellojni.Test
,生成com_example_hellojni_Test.h
,记得拷贝到jni目录下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_hellojni_Test */
#ifndef _Included_com_example_hellojni_Test
#define _Included_com_example_hellojni_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojni_Test
* Method: callC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_hellojni_Test_callC(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
###生成方法签名
在project/bin/classes目录,执行javap -s com.example.hellojni.Test
,生成各个方法的签名。签名说明了方法的参数和返回值类型。
Compiled from "Test.java"
public class com.example.hellojni.Test extends java.lang.Object{
public com.example.hellojni.Test();
Signature: ()V
public native void callC();
Signature: ()V
public void print(java.lang.String);
Signature: (Ljava/lang/String;)V
public int add(int, int);
Signature: (II)I
}
生成的签名,括号里的代表参数,括号外的内容表示返回值。()V
代表参数为空,返回值为void。(II)I
代表参数为两个int,返回值为int。
###实现native方法
在C文件中:
- 添加头文件
* #include "com_example_hellojni_Test.h"
- 添加native方法的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
JNIEXPORT void JNICALL Java_com_example_hellojni_Test_callC(JNIEnv *env, jobject thiz) {
LOGE("start");
char* name = "com/example/hellojni/Test";
// 根据包名获取类
jclass test = (*env)->FindClass(env, name);
// 获取要调用的方法,第三个参数是方法名,第四个参数是方法签名
jmethodID method = (*env)->GetMethodID(env, test, "print", "(Ljava/lang/String;)V");
LOGE("before call");
(*env)->CallVoidMethod(env, thiz, method, (*env)->NewStringUTF(env, "hello jni"));
LOGE("after call");
}