JNI调用Java构造方法,父类方法

时间:2021-10-14 19:29:47

本文基于此项目Hello JNI

本文用到的函数:Call< Type>Method, CallNonvirtual< Type>Method

JNIDemo.java创建两个native方法

    //访问构造方法
public native void accessConstructMethod();

//访问父类方法
public native void accessParentMethod();

创建一个父类:Person和一个子类:Student

Person.java

package com.test.git.jnidemo.JniUtil;

import android.util.Log;

/**
* Created by lk on 16/9/26.
*/


public class Person {
private static final String TAG = "Person";
protected String name;
protected int age;

public Person(){

}


public Person(String name, int age){
this.name = name;
this.age = age;
}


@Override
public String toString() {
return "name:" + name + " age:" + age;
}

public void printPerson(){
Log.i(TAG, "printPerson: " + toString());
}

public void eat(){
Log.i(TAG, "eat: Person");
}
}

Student.java

package com.test.git.jnidemo.JniUtil;

import android.util.Log;

/**
* Created by lk on 16/9/26.
*/


public class Student extends Person{
private static final String TAG = "Student";

public Student(String name, int age){
this.name = name;
this.age = age;
}

@Override
public void eat() {
super.eat();
Log.i(TAG, "eat: Student");
}
}

com_test_git_jnidemo_JniUtil_JniDemo.h添加相应头文件方法

JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessConstructMethod
(JNIEnv *, jobject);

JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessParentMethod
(JNIEnv *, jobject);

JniDemo.cpp

调用Java构造方法,并执行相应对象的实例方法

此处初始化的是有参数的构造方法,然后通过生成的Person对象,调用相应的printPerson方法。

JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessConstructMethod
(JNIEnv *env, jobject jobj){
//1.获取package com.test.git.jnidemo.JniUtil目录下Person的jclass
jclass cls = env->FindClass("com/test/git/jnidemo/JniUtil/Person");
//2.获取Person的构造函数ID
jmethodID mid = env->GetMethodID(cls, "<init>", "(Ljava/lang/String;I)V");
// jobject jniDemo = env->NewObject(cls, mid);
//3.初始化构造函数(此处传递了参数)
jobject jniDemo = env->NewObject(cls, mid, env->NewStringUTF("小明"), 10);
//4.获取Person的printPerson方法ID
jmethodID pritid = env->GetMethodID(cls, "printPerson", "()V");
//5.调用Person的printPerson方法
env->CallVoidMethod(jniDemo, pritid);
};

调用父类的方法

JNIEXPORT void JNICALL Java_com_test_git_jnidemo_JniUtil_JniDemo_accessParentMethod
(JNIEnv *env, jobject jobj){
//1.获取Student的jclass
jclass jcls = env->FindClass("com/test/git/jnidemo/JniUtil/Student");
//2.获取Student的构造方法ID
jmethodID mid = env->GetMethodID(jcls, "<init>", "(Ljava/lang/String;I)V");
//3.实例化Student并传递参数
jobject jcobj = env->NewObject(jcls, mid, env->NewStringUTF("小学生"), 5);
//4.获取父类的jclass
jclass jpcls = env->FindClass("com/test/git/jnidemo/JniUtil/Person");
//5.获取子类的eat方法ID
jmethodID peatID = env->GetMethodID(jcls, "eat", "()V");
//直接调用子类方法
// env->CallVoidMethod(jcobj, peatID);
//6.调用父类方法
env->CallNonvirtualVoidMethod(jcobj, jpcls, peatID);
};

MainActivity

        jd.accessConstructMethod();
jd.accessParentMethod();

运行结果:

09-26 16:00:08.124 10098-10098/? I/Person: printPerson: name:小明  age:10
09-26 16:00:08.124 10098-10098/? I/Person: eat: Person