JNI学习2.jni函数调用java方法

本文详细介绍了如何在JNI函数中调用Java类的方法,通过实例展示了获取字节码、方法ID、实例化对象及调用方法的步骤。讲解了FindClass、GetMethodID等关键函数的使用,并强调了在JNI中调用Java方法时env和jobj的重要性。
摘要由CSDN通过智能技术生成

jni函数除了要靠c++代码实现功能之外,在一些情况下还需要调用java里的方法来实现一些功能。

解决问题:在jni函数中调用特定java类的特定方法。

新建一个java类:

package com.example.hello_cmake;

import android.util.Log;

public class TestCallBack {
    static {
        System.loadLibrary("native-lib");
    }
    //回调方法 里面调用了add
    public native void callBackAdd();

    public int add(int x,int y){
        Log.d("CALLBACK","add x= "+x+"y="+y);
        return x+y;
    }
}

在TestCallBack类中声明了两个函数,一个是add,这个函数显然是java方法;另一个是CallBackAdd,该方法是个jni函数。

我们在该jni函数实现调用add的功能。

extern "C"
JNIEXPORT void JNICALL
Java_com_example_hello_1cmake_TestCallBack_callBackAdd(JNIEnv *env, jobject jobj) {
    //1得到字节码
    jclass jclazz = env->FindClass("com/example/hello_cmake/TestCallBack");
    //2得到方法
    jmethodID jmethodIds = env->GetMethodID(jclazz,"add","(II)I");
    //3实例化
    jobject object = env->AllocObject(jclazz);
    //4调用方法
    env->CallIntMethod(object,jmethodIds,100,1);
}

从代码中可以看出,当jni函数需要调用java方面的东西的时候,env和jobj就派上用场了。

第一步:得到字节码,也就是得到要调用的java方法所属的类。

这里需要注意com.example.hello_cmake.TestCallBack是类的完整路径,但是识别的时候是以Linux标准进行的,因此里面的.要替换成/来表示路径。

findclass方法是泛用性比较强的得到字节码的方式,通过该函数可以令jni函数任意调用java各个类里面的java方法。另外一种得到字节码的方式是:

jclass a_class = env->GetObjectClass(instance);

getobject方法只能得到jni函数所属的类的字节码,也就是说只能调用与该jni函数所属同类的java方法,泛用性大打折扣。

第二步:得到要调用的java方法的id。

这里注意参数中第二个是java方法的名字,第三个是java方法的签名。方法签名怎么查看可以参考这篇文章查看java函数签名

第三步:实例化一个对象。

在java中,类的成员方法必须以实例调用的形式调用,因此必须实例化一个对象,才能调用成员函数add。

第四步:调用方法。

调用方法的函数参数中,前两个分别为实例与方法的ID,后面的参数则是调用的java方法的参数。

jni函数本身也算是java类的一个成员方法,在调用的时候,需要先实例化TestCallBack类,再进行调用。

Android JNI学习路线可以按照以下步骤进行: 1. 了解JNI的基本概念和作用:JNIJava Native Interface)是Java提供的一种机制,用于实现Java与其他编程语言(如C、C++)之间的交互。它允许在Java代码中调用本地代码(Native Code),并且可以在本地代码中调用Java代码。 2. 学习JNI的基本语法和规则:JNI使用一组特定的函数和数据类型来实现Java与本地代码之间的交互。你需要学习如何声明本地方法、如何在Java代码中调用本地方法、如何在本地代码中调用Java方法等。 3. 学习JNI的数据类型映射:JNI提供了一套数据类型映射规则,用于将Java数据类型映射到本地代码中的数据类型。你需要学习如何处理基本数据类型、对象类型、数组类型等。 4. 学习JNI的异常处理:在JNI中,Java代码和本地代码之间的异常处理是非常重要的。你需要学习如何在本地代码中抛出异常、如何在Java代码中捕获异常等。 5. 学习JNI的线程处理:JNI允许在本地代码中创建和操作线程。你需要学习如何创建和销毁线程、如何在线程之间进行通信等。 6. 学习JNI的性能优化:JNI涉及到Java代码和本地代码之间的频繁切换,因此性能优化是非常重要的。你需要学习如何减少JNI调用的次数、如何避免不必要的数据拷贝等。 7. 学习JNI的调试和测试:在开发JNI程序时,调试和测试是非常重要的。你需要学习如何使用调试器调试本地代码、如何进行单元测试等。 8. 学习JNI的进阶主题:一旦掌握了基本的JNI知识,你可以进一步学习JNI的进阶主题,如JNIJava虚拟机的交互、JNI与动态链接库的交互、JNI与多线程的交互等。 总结起来,Android JNI学习路线包括了基本概念、基本语法、数据类型映射、异常处理、线程处理、性能优化、调试和测试以及进阶主题等内容。通过系统地学习这些知识,你将能够更好地理解和应用JNI技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值