JNI之常见技巧与陷阱

预告

后续可能会推更一个FFmpeg系列的入门博客,大概涉及到FFmpeg解封装、FFmpeg编解码、FFmpeg进行音频重采样、使用FFMpeg将mp3转码成aac、使用FFmpeg合并拼接音视频等。

另外如果有时间可能也会更新几篇关于ffplay的文章,敬请关注。

本文将作为JNI系列的一个结尾,下面是笔者在学习使用JNI的所记录的一些笔记与技巧。

JNIEnv的线程限制

一个JNIEnv指针仅在其相关联的线程中有效。你不能将这个指针从一个线程中传递给另一个线程,或者在多线程中缓存和使用它。Java虚拟机在同一个线程的连续调用中传递给本地方法相同的JNIEnv指针,但是从不同线程中调用本地方法时传递的是不同的JNIEnv指针。应当避免缓存一个线程的JNIEnv指针并在另一个线程中使用指针的常见错误。

本地引用(局部引用)仅在创建它的线程中有效。你不能将本地引用从一个线程中传递到另一个线程。每当有多个线程可能使用相同引用的可能性时,应始终将本地引用转换为全局引用。

JNIEnv是用作线程局部存储。因此,使用者不能在多线程间共享一个JNIEnv变量。如果在一段代码中没有其它办法获得它的JNIEnv,使用者可以共享JavaVM对象,使用GetEnv来取得该线程下的JNIEnv。

如果你使用AttachCurrentThread连接(attach)了Native进程,正在运行的代码在线程分离(detach)之前绝不会自动释放局部引用。使用者创建的任何局部引用必须手动删除。通常,任何在循环中创建局部引用的Native代码可能都需要做一些手动删除。

全局获取JNIEnv

一个JNIEnv指针仅在与其相关联的线程中有效。对于本地方法,这通常不是问题,因为他们从虚拟机接受JNIEnv指针作为第一个参数。然而有时候可能不需要直接从虚拟机调用的本地代码来获取属于当前线程的JNIEnv接口指针。例如通过JNI在Native开启了一个子线程处理某些任务,在这些任务处理完毕后需要将处理结果回调给java层。
这种情况可以通过缓存JavaVM获取当前线程的JNIEnv然后进行java方法的回调。

当System加载一个本地库时,虚拟机会在本地库中查找下述的导出的程序入口:

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserv
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值