android JNI层线程回调Java函数
今天,簡單講講android的jni如何使用jni回調java函數。
之前,我寫了部分jni的博客,講的都是如何從android的java代碼調用jni的函數。最近,需要做一個新的功能,在jni的C函數里,需要開一個線程,不停回調java的函數。開始查了很多資料,最終是完成了效果。這里記錄一下。
需要調用的java的函數:
/** * * @param datas * @param dataSize * @param sync_code * @param frametype * @param frameno * @param channel * @param tv_sec * @param tv_msec */ public void decodeData(byte[] datas, int dataSize,int sync_code,int frametype,int frameno,int channel,int tv_sec,int tv_msec,int hStream) {}
二.在jni里首先進行回調java函數:
?1.首先定義一個保存變量的結構體。
//記錄類相關的信息 typedef struct ClassInfo {JavaVM *jvm; //保存java虛擬機,這是在新線程中能夠回調到java方法的最重要的參數. jobject obj; //保存java對象 jmethodID callbackMethodId; //保存methodID jmethodID receiveDeviceEventId; //保存methodID }ClassInfo; //定義一個全局的ClassInfo ClassInfo gClassInfo = {0};
2.對結構體的變量初始化。
說明一下初始化的內容,首先通過GetJavaVM獲取到java虛擬機,然后通過FindClass獲取調用jni的類,這里必須注意一點,就是這里獲取的類只能是調用jni的類,不能是其他類。我調用其他的類,出現崩潰問題。然后通過GetMethodID獲取java函數。最后,通過NewGlobalRef新建了回調函數所在的類的實體變量。因為我這里回調的函數不是靜態函數,所以需要新建實體類。
這里需要注意java函數變量對應的簽名,java函數是
public void decodeData(byte[] datas, int dataSize,int sync_code,int frametype,int frameno,int channel,int tv_sec,int tv_msec,int hStream)
對應的獲取函數ID的jni是:
gClassInfo.callbackMethodId = (*env).GetMethodID(cls, "decodeData", "([BIIIIIIII)V");這個函數簽名比較重要,也比較復雜,我會在寫一遍博客來講解。
具體的講解如下:
在本地方法中調用Java對象的方法的步驟:
1)獲取你需要訪問的Java對象的類
FindClass通過傳java中完整的類名來查找java的class
GetObjectClass通過傳入jni中的一個java的引用來獲取該引用的類型。
他們之間的區別是,前者要求你必須知道完整的類名,后者要求在Jni有一個類的引用。
2)獲取MethodID,調用方法
GetMethodID 得到一個實例的方法的ID
GetStaticMethodID 得到一個靜態方法的ID
3)獲取對象的屬性
GetFieldID 得到一個實例的域的ID
GetStaticFieldID 得到一個靜態的域的ID
JNI通過ID識別域和方法,一個域或方法的ID是任何處理域和方法的函數的必須參數。
3.在線程調用java函數
這里首先獲取到線程的JNIEnv,然后通過CallVoidMethod調用java的decodeData函數。
具體的調用函數的代碼和函數的返回值相關,對應規則如下:
Instance Method Calling Routines:
| CallVoidMethod | void |
| CallObjectMethod | jobject |
| CallBooleanMethod | jboolean |
| CallByteMethod | jbyte |
| CallCharMethod | jchar |
| CallShortMethod | jshort |
| CallIntMethod | jint |
| CallLongMethod | jlong |
| CallFloatMethod | jfloat |
| CallDoubleMethod | jdouble |
android JNI層線程回調Java函數就講完了。
就這么簡單。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的android JNI层线程回调Java函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android jni jbyteArr
- 下一篇: android 获取apk的版本信息