JNI中FindClass失败问题

由于最近需要写一些jni代码,当然也踩了一些坑,现在梳理一下;写jni访问java层时如果FindClass失败,轻则会导致访问java层的方法失败,处理不当时会导致native层崩溃。

究其原因一般由两种:

原因一:

java类名称字符串的格式错误导致,需要注意以下几点:

1、JNI 类名称以软件包名称开头,并用斜线分隔,例如 java/lang/String。
2、果您要查找某个数组类,则需要以适当数量的英文方括号开头,并且还必须用“L”和“;”将该类括起来,因此 String 的一维数组将是 [Ljava/lang/String; 。
3、查找java层的内部类,需要在外部类签名的基础上使用 $ 符号隔开,例如:FindClass(“com/jninewjavaclass/Test$T”);

这种情形通常比较简单可以比较快速的定位出来,总的来说就是类签名书写错误导致的问题;

原因二

另一种情况通常出现线多线程中,也就是通常说的多线程FindClass失败问题,或则从native线程调起java层中,但二者出错的原理一致,

android开发者文档上给出的解释大致如下:

FindClass 要在你的代码关联的类加载器中启动类搜索。它会检查调用堆栈,如果你自行创建的线程,这时应用中没有堆栈帧。如果从此线程调用 FindClass,JavaVM 会在“系统”类加载器(而不是与应用关联的类加载器)中启动,因此尝试查找特定于应用的类将失败。

通俗点来来说就是:

JNI 中所有的 findclass 都必须是java调用下来才有效,由别的native线程(C++)直接调起时,由于没有 java 堆栈是不能找到 java的 class的,会导致findClass失败;

解决该问题的方式:
在首次从java层调用下来时,在FindClass成功后,将 jclass对象进行newGlobalRef 保存起来,后面再次使用时使用该成员变量即可;

参考文档:

https://developer.android.com/training/articles/perf-jni#faq_FindClass

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值