使用NDK进行JNI编程与实践五:使用C/C++代码回调java类中方法

一、需求:
我们将本地方法和被调用的java类公共方法放在同一个类中,本地方法用于调用C/C++代码,在C/C++代码中实现逻辑,用于调用java中公共方法,公共方法中可添加打印之类的确认是否调用成功,逻辑梳理:

java native method ---> C/C++ method ---> java public method

二、示例:

  1. 使用C++代码回调java的add函数:
    /* JNI回调java函数:调用addSum */
    public native void callAddSum();
    /* java公共函数:addSum */
    public void addSum(int x, int y){
        Log.e("jiyi", "addSum: " + (x + y));
    }

c++函数:

/* 回调java类中的addSum函数:传入两个int型参数 */
JNIEXPORT void JNICALL Java_com_example_jnitest_JNITest_callAddSum
        (JNIEnv *env, jobject jobj)
{
    /* 通过包名找到Java中的类名 */
    jclass clazz = env->FindClass("com/example/jnitest/JNITest");
    if (clazz == 0)
    {
        LOGE("failed to find class JNITest");
    }
    else
    {
        LOGE("find class JNITest succeed!");
    }

    /* 获取java类中方法id:参数一为类对象,参数二为java中方法名,参数三为方法唯一签名 */
    jmethodID jId = env->GetMethodID(clazz, "addSum", "(II)V");
    if (jId == 0)
    {
        LOGE("failed to find method in java!");
    }
    else
    {
        LOGE("find method succeed!");
    }

    /* 调用java中的方法 */
    env->CallVoidMethod(jobj, jId, 10, 20);
}
  1. 使用C/C++代码回调callStrFromJni函数:
    /* JNI回调java函数:调用StrFromJni */
    public native void callStrFromJni();
    /* java公共函数:addSum */
    public void StrFromJni(String str){
        Log.e("jiyi", "StrFromJni: " + str);
    }

C++代码:

/* 回调java类中的StrFromJni方法:传入参数String */
JNIEXPORT void JNICALL Java_com_example_jnitest_JNITest_callStrFromJni
        (JNIEnv *env, jobject jobj)
{
    /* 通过包名找到Java中的类名 */
    jclass clazz = env->FindClass("com/example/jnitest/JNITest");
    if (clazz == 0)
    {
        LOGE("failed to find class JNITest");
    }
    else
    {
        LOGE("find class JNITest succeed!");
    }

    /* 获取java类中方法id:参数一为类对象,参数二为java中方法名,参数三为方法唯一签名 */
    jmethodID jId = env->GetMethodID(clazz, "StrFromJni", "(Ljava/lang/String;)V");
    if (jId == 0)
    {
        LOGE("failed to find method in java!");
    }
    else
    {
        LOGE("find method succeed!");
    }

    /* 调用java中的方法 */
    env->CallVoidMethod(jobj, jId, env->NewStringUTF("I'm from JNI!"));
}

二、总结:
使用C/C++代码回调java中方法其实跟修改java中的属性逻辑是一样的,都是先获取java对象的字节码,然后获取Java方法的id之后,再回调对应的java方法。

代码路径:

https://github.com/jiyi666/apk-demo/tree/master/JNITest
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值