References: http://blog.csdn.net/banketree/article/details/40535325 百度百科:http://baike.baidu.com/link?url=G_C-p8YK5fnYffQFRure1sr80yBHmmP5VMMyKbGPzWiGWhKldWXfoLaQKEwJcS-vP_i9dLg79rSrni69wJ_ima 百度文库:http://wenku.baidu.com/link?url=09Ca0f6iD-jgb4c1m5Uao8bL_z_vYVGs39k7cE5NZwACaVYNpOZJH7NoHloAh0sABFU9j_haF0erMBPKs6VfXQNJ7EI92AETUomwvWvylXK
http://wenku.baidu.com/view/107c3d37b90d6c85ec3ac671.html?re=view
JNI Introduce –>你可以使用JNI来实现“本地方法”(native methods),并在java程序中调用它们。 –>JNI支持一个“调用接口”(invocation interface),它允许你把一个JVM嵌入到本地程序中。本地程序可以链接一个实现了JVM的本地库,然后使用“调用接口”执行JAVA语言编写的软件模块。JNIEnv && JavaVM –>JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局只有一个 –>JNIEnv : JavaVM 在线程中的代表, 每个线程都有一个, JNI 中可能有很多个 JNIEnv;编写JNI_Thread.c文件,在mainThread()函数里启动5个子线程,在子线程函数里回调java中的静态方法fromJNI()来输出当前子线程是第几个被启动的线程。完整的内容如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<unistd.h> 4 #include<pthread.h> 5 6 #include<jni.h> 7 #include<android/log.h> 8 9 #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))10 #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))11 #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))1213 //线程数14 #define NUMTHREADS 51516 //全局变量17 JavaVM *g_jvm = NULL;18 jobject g_obj = NULL;192021 void *thread_fun(void* arg)22 {23 JNIEnv *env;24 jclass cls;25 jmethodID mid;2627 //Attach主线程28 if((*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL) != JNI_OK)29 {30 LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);31 return NULL;32 }33 //找到对应的类34 cls = (*env)->GetObjectClass(env,g_obj);35 if(cls == NULL)36 {37 LOGE("FindClass() Error.....");38 goto error;39 }40 //再获得类中的方法41 mid = (*env)->GetStaticMethodID(env, cls, "fromJNI", "(I)V");42 if (mid == NULL)43 {44 LOGE("GetMethodID() Error.....");45 goto error; 46 }47 //最后调用java中的静态方法48 (*env)->CallStaticVoidMethod(env, cls, mid ,(int)arg);49 5051 error: 52 //Detach主线程53 if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK)54 {55 LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);56 }57 5859 pthread_exit(0);60 }6162 //由java调用以创建子线程63 JNIEXPORT void Java_com_nan_thread_MyThreadActivity_mainThread( JNIEnv* env, jobject obj)64 {65 int i;66 pthread_t pt[NUMTHREADS];67 68 for (i = 0; i < NUMTHREADS; i++)69 //创建子线程70 pthread_create(&pt[i], NULL, &thread_fun, (void *)i);71 }727374 //由java调用来建立JNI环境75 JNIEXPORT void Java_com_nan_thread_MyThreadActivity_setJNIEnv( JNIEnv* env, jobject obj)76 {77 //保存全局JVM以便在子线程中使用78 (*env)->GetJavaVM(env,&g_jvm);79 //不能直接赋值(g_obj = obj)80 g_obj = (*env)->NewGlobalRef(env,obj);81 }828384 //当动态库被加载时这个函数被系统调用85 JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)86 {87 JNIEnv* env = NULL;88 jint result = -1; 8990 //获取JNI版本91 if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4) != JNI_OK)92 {93 LOGE("GetEnv failed!");94 return result;95 }9697 return JNI_VERSION_1_4;98 }Android.mk
1 LOCAL_PATH := $(call my-dir) 2 3 include $(CLEAR_VARS) 4 5 LOCAL_MODULE := JNIThreads 6 LOCAL_SRC_FILES := JNI_Threads.c 7 8 LOCAL_LDLIBS := -llog 910 include $(BUILD_SHARED_LIBRARY)新闻热点
疑难解答