android jni 回调 java_android linux线程通过JNI回调java函数 | 学步园
Linux線程通過JNI回調JAVA函數
最近做的一個小工程需要用到回調函數,由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.(Handler.java:121)
at com.cao.android.demos.handles.HandleTestActivity$MyThread$1.(HandleTestActivity.java:86)
at com.cao.android.demos.handles.HandleTestActivity$MyThread.run(HandleTestActivity.java:86)
這樣從linux線程通過JNI調用到JAVA的函數就完全可以啦,第一次作記錄,如果 有錯誤,歡迎斧正!
總結
以上是生活随笔為你收集整理的android jni 回调 java_android linux线程通过JNI回调java函数 | 学步园的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react 点击两次_javascrip
- 下一篇: java正则表达式匹配数字范围_在jav