android jni 结构体_Android应用开发Android JNI-c/c++调用java方法
本文將帶你了解Android應用開發Android JNI-c/c++調用java方法,希望本文對大家學Android有所幫助。
"
Android ? JNI-c/c++調用java方法,在使用ndk開發的時候,java調用c/c++方法是必須要的。但是很多時候,c/c++有callback需要反饋給java的時候(比如IM通訊登錄成功信息和一些異常信息),就需要c/c++調用java方法了。
在看這篇文章之前,必須對JNI有一些基礎的了解,比如java調用c/c++方法,java和c/c++ ? jni在一些基本類型上的對應(int對應jint等)。
那么現在介紹一下c/c++調用java方法的基本步驟:
1.需要把java方法所在類的實例通過JNI方法傳到c/c++
java:JNI, 這是c需要回調的java方法,然后通過調用自身init()方法,把java實例傳到c層
?
1
2
3
4
5
6
class JNI {
public native void init(JNI obj);
public void error(int code) {
Log.i(""JNI"", ""c++ call error ? "");
}
}
c:這里把java傳遞進來的objListener,保存到c的jniobj結構體內。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
JNIEXPORT jint JNICALL Java_com_arcvideo_rtcmessage_JNI_init(
JNIEnv *env,
jobject oj,
jobject objListener,
)
{
if(objListener == MNull){
MVLOG(""objListener is null"");
}else
{
MVLOG(""get ? java obj"");
jniobj->g_obj = ? env->NewGlobalRef(objListener);
}
return res;
}
typedef struct _tagJNIObj{//這個是剛才保存java實例的結構體,在還有其他參數
jmethodID JNI_error;
JavaVM* g_jvm;
JNIEnv* g_ThreadEnv;
jclass g_class;
jobject g_obj;
MHandle g_h;
}JNIObj;
static JNIObj* jniobj = MNull;
2.在c層拿到java class
c:通過jni提供的FindClass方法和完整類名,可以拿到class引用
?
1
2
static const char* const DL_CLASS_NAME = ? ""com/arcvideo/rtcmessage/JNI"";
jniobj->g_class = env->FindClass(DL_CLASS_NAME);
3.在c層拿到java method
c:根據剛才拿到的java class引用有jni提供的GetMethodID方法,和方法名,入參,就可以拿到method引用
?
1
2
3
4
5
6
// error
jniobj->JNI_error = ? env->GetMethodID(jniobj->g_class, ""error"",
""(I)V"");
if(jniobj->JNI_error == ? MNull){
MVLOG(""create ? JNI_error is error"");
}
4.調用method
c:在需要調用的地方調用這個java方法,
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static void error(MDWord code, MVoid* pObj)
{
MVLOG(""RtcMessageJNI ? error is in code : %d"", code );
if(jniobj->g_ThreadEnv == ? MNull)
{
MVLOG(""attach ? current thread start"");
jniobj->g_jvm -> ? AttachCurrentThread(&jniobj->g_ThreadEnv, MNull);
if(jniobj->g_ThreadEnv == ? MNull){
MVLOG(""attach ? current thread is error"");
return;
}
}
if(jniobj && ? jniobj->JNI_error){
MVLOG(""RtcMessageJNI error is called"");
//這里是最關鍵的調用過程,通過JNI提供的CallVoidMethod,來調用,加入參數,class引用,method應用,已經入參,這樣調用java方法就完成了。
jniobj->g_ThreadEnv->CallVoidMethod(jniobj->g_obj, ? jniobj->JNI_error,
(int)code);
}
if(jniobj->g_jvm){
MVLOG(""RtcMessageJNI error method ? detach"");
jniobj->g_jvm->DetachCurrentThread();
jniobj->g_ThreadEnv = ? MNull;
}
}
這里在調用java方法的時候調用了,AttachCurrentThread和DetachCurrentThread方法,這是必須的,如果不調用AttachCurrentThread就拿不到線程的引用,會報錯誤。然后在調用結束的時候要調用DetachCurrentThread,也就是釋放線程。根據個人經驗,最好每次調用java方法結束的時候都調用DetachCurrentThread,這樣基本不會出錯。
"
本文由職坐標整理并發布,希望對同學們有所幫助。了解更多詳情請關注職坐標移動開發之Android頻道!
總結
以上是生活随笔為你收集整理的android jni 结构体_Android应用开发Android JNI-c/c++调用java方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: d3.js 旋转图形_苏教版三年级数学上
- 下一篇: latex在论文中添加行号