android jni 回调 java_Android JNI回调java接口方法学习

代码主要分为Java层(java代码)和JNI层(c语言代码),首先看看Java层的代码(Native.java)。

e0779903cd65e6c9e619a489add7ad15.png

如上所示,Java层与JNI层的接口代码主要封装在Native类中,该类定义了三个native函数,分别完成jni库的初始化,调用jni层开启线程,调用jni层关闭线程等功能。并且提供一个回调函数(onNativeCallback),供jni层调用,并在回调函数中打印count的值。

再看看JNI层是如何开启线程并回调Java层的(native.c),关键的地方都在代码中进行了注释:

1. 头文件包含和全局变量的定义

255d6a5ddfac09512083af4d3c9bf68b.png

2. 初始化函数的实现

dbbaacca968cd880b83a61d28400dd05.png

3. 开启关闭线程的实现

775ec0f4c3c8f84c3b93c98005b1e98c.png

4. 线程的实现(关键)

77fb92cad7432319be728dbe311b90ca.png

由上述代码可以看到,JNI层通过pthread库完成了线程的创建,需要特别注意的是,JNI层的线程中,必须通过全局的JavaVM来获取到环境变量,也必须通过全局的jobject获取java类对象,从而找到java端的函数,进行回调。

1. 在onload的时候保存JavaVM指针。

2. 在自定义jni方法里(该方法须在callback方法使用前调用,例如初始化方法)保存callback方法所在对象,

且该对象需要创建一个全局引用以便在线程方法里使用,默认是local ref,函数执行完会被虚拟机释放;

另外自定义jni方法和callback方法在同一个类里,所以在调用自定义方法时能保存一致的jobject  。

3. 也是在自定义jni方法中,通过class获得该callback的method ID。

参考:http://blog.csdn.net/zhengxinwcking/article/details/24718499

参考:http://ticktick.blog.51cto.com/823160/1358558/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android NDK中,我们可以使用JNIJava Native Interface)来实现C/C++代码和Java代码的相互调用。 下面是一个简单的例子,展示了如何在NDK中调用Java层的方法。 首先,在Java层中创建一个类,并在其中声明一个需要被C/C++回调方法: ```java public class MyCallback { public void processData(byte[] data) { // 处理数据的逻辑 } } ``` 然后,在C/C++代码中,我们需要使用JNI来获取Java层的MyCallback对象,并调用其processData方法。具体步骤如下: 1. 首先,需要在C/C++代码中引入JNI头文件: ```c++ #include <jni.h> ``` 2. 获取Java层的MyCallback对象: ```c++ JNIEnv* env; JavaVM* jvm; // 获取当前线程的JNIEnv指针 jvm->AttachCurrentThread(&env, NULL); // 获取MyCallback类 jclass myCallbackClass = env->FindClass("com/example/MyCallback"); // 获取MyCallback对象 jmethodID constructor = env->GetMethodID(myCallbackClass, "<init>", "()V"); jobject myCallbackObj = env->NewObject(myCallbackClass, constructor); ``` 3. 调用MyCallback对象的processData方法: ```c++ // 获取processData方法的ID jmethodID processDataMethod = env->GetMethodID(myCallbackClass, "processData", "([B)V"); // 构造byte[]对象 jbyteArray data = env->NewByteArray(size); env->SetByteArrayRegion(data, 0, size, (jbyte*)buf); // 调用processData方法 env->CallVoidMethod(myCallbackObj, processDataMethod, data); ``` 最后,记得在C/C++代码中释放JNI相关资源: ```c++ jvm->DetachCurrentThread(); env->DeleteLocalRef(myCallbackClass); env->DeleteLocalRef(myCallbackObj); env->DeleteLocalRef(data); ``` 以上就是在NDK中实现线程回调Java方法的基本步骤。需要注意的是,在调用Java方法时,需要使用JNIEnv指针。此外,如果在多线程环境下操作JNI,需要使用jvm->AttachCurrentThread()方法获取当前线程的JNIEnv指针。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值