Android-jni(10)-jni调用java父类方法

jni调用java父类方法,在知道这个之后,我感觉jni能做的事真是厉害。我们一起来看看它与java的不同

一. jni调用java父类方法

先做个准备:

  1. 准备一个Java父类和子类,People和Beibi:
public class People {
    private static final String TAG = People.class.getSimpleName();

    /**
     * 说方法,在其中调用下sayAge
     */
    public void say() {
        Log.d(TAG, "people say");
        sayAge();
    }

    public void sayAge() {
        Log.d(TAG, "people say age");
    }
}

public class Beibi extends People {
    private static final String TAG = Beibi.class.getSimpleName();
    private int age;
    private String name;

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

    /**
     * 重写的父类说方法
     */
    @Override
    public void say() {
        Log.d(TAG, "beibi say:my name is " + name);
    }

    /**
     * 重写的父类说方法
     */
    @Override
    public void sayAge() {
        Log.d(TAG, "beibi say:my age is " + age);
    }
}
  1. 先来java方法来调用下say
 /*使用java来创建进行调用say方法*/
        People beibi = new Beibi(12, "小北鼻");
        beibi.say();
  • 输出
beibi say:my name is 小北鼻

这是我们正常情况下的多态的情况,不用说明了,至少我的理解是,正常使用情况下,只要实例是Beibi,在外部调用say方法,怎么调用都是Beibi的say,是调用不到People的say的。

接下来我们看jni,步骤:

  1. 创建Beibi的实例,并调用Beibi的say方法
  2. 依旧使用北鼻的实例,再调用People的say方法:使用CallNonvirtualVoidMethod

直接上代码,代码中有注释:

//1. 找Beibi的class
    jclass class_beibi = env->FindClass("shixin/ndkdemo/supermethod/Beibi");
    if (class_beibi == NULL) {
        LOGE("beibi class 寻找失败");
        return 1;
    }

    //2. 找Beibi的构造方法id,参数是int,String
    jmethodID jmethodID_init = env->GetMethodID(class_beibi, "<init>",
                                                "(ILjava/lang/String;)V");

    if (jmethodID_init == NULL) {
        LOGE("beibi 构造方法 寻找失败");
        return 1;
    }

    //3. 创建Beibi对象
    jobject obj_beibi = env->NewObject(class_beibi, jmethodID_init, age_, name_);
    if (obj_beibi == NULL) {
        LOGE("beibi 对象创建失败");
        return 1;
    }

    //4. 调用Beibi的say方法
    jmethodID jmethodID1_say = env->GetMethodID(class_beibi, "say", "()V");
    if (jmethodID1_say == NULL) {
        LOGE("beibi say方法寻找失败");
        return 1;
    }
    env->CallVoidMethod(obj_beibi, jmethodID1_say);

    /*···········下面来调用父类方法··········*/
    //5. 找到父类,People的class
    jclass class_people = env->FindClass("shixin/ndkdemo/supermethod/People");
    if (class_people == NULL) {
        LOGE("People class 寻找失败");
        return 1;
    }

    //6. 找到People的say方法id
    jmethodID jmethodID1_people_say = env->GetMethodID(class_people, "say", "()V");
    if (jmethodID1_people_say == NULL) {
        LOGE("people say方法 寻找失败");
        return 1;
    }

    //7. 调用父类方法 使用 CallNonvirtualVoidMethod 方法,参数:实例对象,class,方法id
    env->CallNonvirtualVoidMethod(obj_beibi, class_people, jmethodID1_people_say);
  • 输出:
D/Beibi: beibi say:my name is 大北鼻
D/People: people say
D/Beibi: beibi say:my age is 13

在输出就能看到:

  1. 咱们第一步调用Beibi实例的say方法正常调用
  2. 使用Beibi实例来调用父类People的方法,say真的是执行的父类的方法,然后在say中调用的sayAge又因为子类的重写调用的Beibi的sayAge

二. 总结

  1. 使用CallNonvirtualXXMethod可以调用传入实例obj与父类的class和methodid来调用父类的XX返回类型的方法
  2. 第一步仅在指定这个class和methodid的方法有效,对于实例方法中调用的被子类复写的方法依旧会调用到子类的方法
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值