// 1.寻找类 Student
// jclass studentClass = env->FindClass("com/derry/as_jni_project/Student"); // 第一种
jclass studentClass = env->GetObjectClass(student); // 第二种

// 2.Student类里面的函数规则  签名
jmethodID setName = env->GetMethodID(studentClass, "setName", "(Ljava/lang/String;)V");
jmethodID getName = env->GetMethodID(studentClass, "getName", "()Ljava/lang/String;");
jmethodID showInfo = env->GetStaticMethodID(studentClass, "showInfo", "(Ljava/lang/String;)V");

// 3.调用 setName
jstring value = env->NewStringUTF("AAAA");
env->CallVoidMethod(student, setName, value);

// 4.调用 getName
jstring getNameResult = static_cast<jstring>(env->CallObjectMethod(student, getName));
const char *getNameValue = env->GetStringUTFChars(getNameResult, NULL);
LOGE("调用到getName方法,值是:%s\n", getNameValue);

// 5.调用静态showInfo
jstring jstringValue = env->NewStringUTF("静态方法你好,我是C++");
env->CallStaticVoidMethod(studentClass, showInfo, jstringValue);

}

1
2
3

运行结果:

I/JNISTUDY: strChar:九阳神功
D/Student: Java setName name:AAAA
E/JNISTUDY: 调用到getName方法,值是:AAAA
D/Student: showInfo info:静态方法你好,我是C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

# JNI创建JAVA对象

Java对象:

```java
import android.util.Log;

public class Student {

private final static String TAG = Student.class.getSimpleName();

public String name;
public int age;

public String getName() {
return name;
}

public void setName(String name) {
Log.d(TAG, "Java setName name:" + name);
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
Log.d(TAG, "Java setAge age:" + age);
this.age = age;
}

public static void showInfo(String info) {
Log.d(TAG, "showInfo info:" + info);
}

@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}

import android.util.Log;

public class Person {

private static final String TAG = Person.class.getSimpleName();

public Student student;

public void setStudent(Student student) {
Log.d(TAG, "call setStudent student:" + student.toString());
this.student = student;
}

public static void putStudent(Student student) {
Log.d(TAG, "call static putStudent student:" + student.toString());
}
}

JNI层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// C++ 堆 栈 ...
// JNI函数 局部引用,全局引用,...
extern "C"
JNIEXPORT void JNICALL
Java_com_derry_as_1jni_1project_MainActivity_insertObject(JNIEnv *env, jobject thiz) {
/*jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();
jstring str = env->GetStringUTFChars();

// 好习惯:
// 我用完了,我记释放,在我函数执行过程中,不会导致 内存占用多
env->ReleaseStringUTFChars()*/


// 1.通过包名+类名的方式 拿到 Student class 凭空拿class
const char *studentstr = "com/derry/as_jni_project/Student";
jclass studentClass = env->FindClass(studentstr);

// 2.通过student的class 实例化此Student对象 C++ new Student
jobject studentObj = env->AllocObject(studentClass); // AllocObject 只实例化对象,不会调用对象的构造函数

// 方法签名的规则
jmethodID setName = env->GetMethodID(studentClass, "setName", "(Ljava/lang/String;)V");
jmethodID setAge = env->GetMethodID(studentClass, "setAge", "(I)V");

// 调用方法
jstring strValue = env->NewStringUTF("Derry");
env->CallVoidMethod(studentObj, setName, strValue);
env->CallVoidMethod(studentObj, setAge, 99);


// env->NewObject() // NewObject 实例化对象,会调用对象的构造函数


// ==================== 下面是 Person对象 调用person对象的 setStudent 函数等

// 4.通过包名+类名的方式 拿到 Student class 凭空拿class
const char *personstr = "com/derry/as_jni_project/Person";
jclass personClass = env->FindClass(personstr);

jobject personObj = env->AllocObject(personClass); // AllocObject 只实例化对象,不会调用对象的构造函数

// setStudent 此函数的 签名 规则
jmethodID setStudent = env->GetMethodID(personClass, "setStudent",
"(Lcom/derry/as_jni_project/Student;)V");

env->CallVoidMethod(personObj, setStudent, studentObj);

// 规范:一定记得释放【好习惯】
// 第一类
env->DeleteLocalRef(studentClass);
env->DeleteLocalRef(personClass);
env->DeleteLocalRef(studentObj);
env->DeleteLocalRef(personObj);

// 第二类
// env->ReleaseStringUTFChars()

// TODO 局部引用: jobject jclass jstring ... 【函数结束后,会自动释放】
}