现在的位置: 首页 > 综合 > 正文

android linux线程通过JNI回调java函数

2013年12月13日 ⁄ 综合 ⁄ 共 1465字 ⁄ 字号 评论关闭

Linux线程通过JNI回调JAVA函数

 ----->第一次发,有啥错误多包涵呀,转载请注明http://blog.csdn.net/saky0542/article/details/12018981

 

最近做的一个小工程需要用到回调函数,由linux层回调到java层,调试的时候会遇到一些问题,免得忘记,在这里记录一下:

 

JNI的各种数据类型和数据结构我就不详细介绍了,简单说一下

JavaVM *m_jvm;  java虚拟机,这个变量可以在不同的线程里面使用,获取的方法也有很多,可以通过env获取,也可以通过JNI_OnLoad函数来获取
JNIEnv *g_env;     这个是一个线程的相关变量,这里注意的是一个线程的,对于每个线程来说是唯一的,不能在不同的线程里面使用同一个env;

jobject g_obj;        因为java层的代码,native的接口和主activity不是放在同一个class里面,因此把主activity的obj传下来的,方便在JNI层更快的寻找到activity的class
jclass g_class;     为之前的g_obj里面的类对象
int flagthread = 0;  因为特殊原因,我的代码里面的第一个线程为UI线程,之后的线程由底层创建,因为设置一个flag来过滤第一个线程,方便之后的attach和detach

 接下去就是上代码了

 

这是一个回调函数,给linux用的,上报状态的,在代码已经注明了必须attach,不然会报以下错误

E/dalvikvm( 2068): JNI ERROR: non-VM thread making JNI calls
E/dalvikvm( 2068): VM aborting
F/libc    ( 2068): Fatal signal 11 (SIGSEGV) at 0xdeadd00d (code=1), thread 2125 (id.wifimiracast)

 

其实也很好理解,因为大家注意到我的接口并不是标准的JNI接口,这个接口是我自己创建供linux层回调的,一般标准的JNI接口,是直接供java层使用的,那时候的多线程attach其实是attach到UI线程上的,但在linux里面创建了一个线程去回调这个状态函数的时候,并没有涉及到UI线程,所以是到了JNI层的话,必须也得要有一个线程去处理这个回调,下面的就好理解了,JNI线程去回调java的时候,java也必须要有一个线程去处理,下面会讲到。

 

在代码里面可以看到我调用的是statebroadcast这个回调函数

 

这里必须要用handler去处理,不然会报如下错误

 java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:121)

at com.cao.android.demos.handles.HandleTestActivity$MyThread$1.<init>(HandleTestActivity.java:86)
at com.cao.android.demos.handles.HandleTestActivity$MyThread.run(HandleTestActivity.java:86)

 

这样从linux线程通过JNI调用到JAVA的函数就完全可以啦,第一次作记录,如果 有错误,欢迎斧正!

 

抱歉!评论已关闭.