赞
踩
最近遇到一个JNI的问题,同一套代码在Android4.4版本前的设备上运行是OK的,但是在Android5.0之后的设备上就会崩溃,查看logcat发现报JNI DETECTED ERROR IN APPLICATION错误。
(1)第一个错误:
JNI DETECTED ERROR IN APPLICATION: calling static method xxxx with CallxxxxMethodV in call to CallxxxxMethodV
有过JNI编程经验的就会知道,调用方法分static和非static两种,分别会用到
GetStaticMethodID GetMethodID
CallStatic<type>Method Call<type>Method
其中<type>指Int, Long, Char等类型
问题的原因就是编写JNI代码的同事混用了这两种方式,先用了GetStaticMethodID,然后又用的非static的CallIntMethod方法,Android4.4之前版本JNI检查机制没有Android5.0之后的版本严格,所以没有报错,程序也不会崩溃,但正确的方式应该是GetMethodID+Call<type>Method,GetStaticMethodID+CallStatic<type>Method,这个问题解决后又接着又报出了下面的错误。
(2)第二个错误:
JNI DETECTED ERROR IN APPLICATION: native code passing in reference to invalid stack indirect reference table or invalid reference: 0xfff5f1b0
in call to CallVoidMethod <==这一行报错是问题的切入点
这个错误显示是CallVoidMethod的参数非法引用,网上找了一些相关问题的帖子,结合本地代码,发现最有可能的就是线程间不能直接传递JNIEnv和jobject这类线程专属属性值导致,要知道JavaVM是属于Java进程的,每个进程只有一个JavaVM,而这个JavaVM可以被多线程共享,但是JNIEnv和jobject是属于线程私有的,不能共享,那有什么办法解决呢?这里我们不讲JNIEnv的线程间传递,有兴趣的网上可以找到相关帖子,而jobject可以用全局引用的方式在多线程间使用,举个简单的例子:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。