一、概述
JNI编程和Linux上的C/C++编程还是挺相似的,每次java调用JNI中的函数时都会传入有关JVM的一些参数(如JNIEnv,jobject),每次JNI回调java中的方法时都要通过JVM的有关参数来实现,当在JNI中涉及到多线程的话还是有一些不一样的地方,就是要在子线程函数里使用AttachCurrentThread()和DetachCurrentThread()这两个函数,在这两个函数之间加入回调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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 |
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>#include<jni.h>#include<android/log.h>#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))//线程数#define NUMTHREADS 5//全局变量JavaVM *g_jvm = NULL;jobject g_obj = NULL;void
*thread_fun(void* arg){ JNIEnv *env; jclass cls; jmethodID mid; //Attach主线程 if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK) { LOGE("%s: AttachCurrentThread() failed", __FUNCTION__); return
NULL; } //找到对应的类 cls = (*env)->GetObjectClass(env,g_obj); if(cls == NULL) { LOGE("FindClass() Error....."); goto
error; } //再获得类中的方法 mid = (*env)->GetStaticMethodID(env, cls, "fromJNI", "(I)V"); if
(mid == NULL) { LOGE("GetMethodID() Error....."); goto
error; } //最后调用java中的静态方法 (*env)->CallStaticVoidMethod(env, cls, mid ,(int)arg); error: //Detach主线程 if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK) { LOGE("%s: DetachCurrentThread() failed", __FUNCTION__); } pthread_exit(0);}//由java调用以创建子线程JNIEXPORT void
Java_com_nan_thread_MyThreadActivity_mainThread( JNIEnv* env, jobject obj){ int
i; pthread_t pt[NUMTHREADS]; for
(i = 0; i < NUMTHREADS; i++) //创建子线程 pthread_create(&pt[i], NULL, &thread_fun, (void
*)i);}//由java调用来建立JNI环境JNIEXPORT void
Java_com_nan_thread_MyThreadActivity_setJNIEnv( JNIEnv* env, jobject obj){ //保存全局JVM以便在子线程中使用 (*env)->GetJavaVM(env,&g_jvm); //不能直接赋值(g_obj = obj) g_obj = (*env)->NewGlobalRef(env,obj);}//当动态库被加载时这个函数被系统调用JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void
*reserved){ JNIEnv* env = NULL; jint result = -1; //获取JNI版本 if
((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK) { LOGE("GetEnv failed!"); return
result; } return
JNI_VERSION_1_4;} |
原文:http://www.cnblogs.com/porter/p/3578421.html