android jni 回调 java_android linux线程通过JNI回调java函数 | 学步园
Linux線程通過JNI回調(diào)JAVA函數(shù)
最近做的一個小工程需要用到回調(diào)函數(shù),由linux層回調(diào)到j(luò)ava層,調(diào)試的時候會遇到一些問題,免得忘記,在這里記錄一下:
JNI的各種數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)我就不詳細介紹了,簡單說一下
JavaVM *m_jvm;? java虛擬機,這個變量可以在不同的線程里面使用,獲取的方法也有很多,可以通過env獲取,也可以通過JNI_OnLoad函數(shù)來獲取
JNIEnv *g_env;???? 這個是一個線程的相關(guān)變量,這里注意的是一個線程的,對于每個線程來說是唯一的,不能在不同的線程里面使用同一個env;
jobject g_obj;??????? 因為java層的代碼,native的接口和主activity不是放在同一個class里面,因此把主activity的obj傳下來的,方便在JNI層更快的尋找到activity的class
jclass g_class;???? 為之前的g_obj里面的類對象
int flagthread = 0;? 因為特殊原因,我的代碼里面的第一個線程為UI線程,之后的線程由底層創(chuàng)建,因為設(shè)置一個flag來過濾第一個線程,方便之后的attach和detach
接下去就是上代碼了
這是一個回調(diào)函數(shù),給linux用的,上報狀態(tài)的,在代碼已經(jīng)注明了必須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接口,這個接口是我自己創(chuàng)建供linux層回調(diào)的,一般標準的JNI接口,是直接供java層使用的,那時候的多線程attach其實是attach到UI線程上的,但在linux里面創(chuàng)建了一個線程去回調(diào)這個狀態(tài)函數(shù)的時候,并沒有涉及到UI線程,所以是到了JNI層的話,必須也得要有一個線程去處理這個回調(diào),下面的就好理解了,JNI線程去回調(diào)java的時候,java也必須要有一個線程去處理,下面會講到。
在代碼里面可以看到我調(diào)用的是statebroadcast這個回調(diào)函數(shù)
這里必須要用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調(diào)用到JAVA的函數(shù)就完全可以啦,第一次作記錄,如果 有錯誤,歡迎斧正!
總結(jié)
以上是生活随笔為你收集整理的android jni 回调 java_android linux线程通过JNI回调java函数 | 学步园的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: react 点击两次_javascrip
- 下一篇: linux获取ad用户列表,Powers