本文参考了http://www.cnblogs.com/lknlfy/archive/2012/03/16/2400786.html这篇博文,加了点自己的东西

废话不多说,贴代码上来

java的代码:

package com.example.jni_thread_demo;import android.os.Bundle;import android.app.Activity;import android.util.Log;import android.view.Menu;import android.view.View;import android.widget.Button;public class JNI_ThreadActivity extends Activity {private Button mButton = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_jni__thread);mButton = (Button)findViewById(R.id.button);mButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 调用JNI中的函数来启动JNI中的线程mainThread();}});// 初始化JNI环境setJNIEnv();}//由JNI中的线程回调类方法private static void fromJNI(int i){Log.v("Java---------->", ""+i);}       //自己定义的线程回调成员方法private void From_JNI_Again (int i){Log.v("Java_object------------>", ""+i);}// 本地方法private native void mainThread();private native void setJNIEnv();static{System.loadLibrary("JNIThread");}}

jni中的代码:

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<pthread.h>#include<string.h>#include<assert.h>#include<jni.h>#include<android/log.h>#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "jni_thread", __VA_ARGS__))#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "jni_thread", __VA_ARGS__))#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "jni_thread", __VA_ARGS__))// 线程数#define NUMTHREADS 5// 指定要注册的类#define JNIREG_CLASS "com/example/jni_thread_demo/JNI_ThreadActivity"// 全局变量JavaVM* g_jvm = NULL;jobject g_obj = NULL;void* thread_fun(void* arg){JNIEnv *env;jclass cls;jmethodID mid, mid1;// 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("GetStaticMethodID() Error ......");goto error;}// 最后调用java中的静态方法(*env)->CallStaticVoidMethod(env, cls, mid, (int)arg);//获得类中的“成员”方法mid1 = (*env)->GetMethodID(env, cls, "From_JNI_Again", "(I)V");if(mid == NULL){LOGE("GetMethodID() Error ......");goto error;}// 最后调用类中“成员”方法(*env)->CallVoidMethod(env, g_obj, mid1, (int)arg);//错误处理代码error://Detach主线程if((*g_jvm)->DetachCurrentThread(g_jvm) != JNI_OK){LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);}pthread_exit(0);}/* * Class:     com_example_jni_thread_demo_JNI_ThreadActivity * Method:    mainThread * Signature: ()V *//*不用JNI_OnLoad时的复杂命名方式JNIEXPORT void JNICALL Java_com_example_jni_1thread_1demo_JNI_1ThreadActivity_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);}}*//* * Class:     com_example_jni_thread_demo_JNI_ThreadActivity * Method:    setJNIEnv * Signature: ()V *//*不用JNI_OnLoad时的复杂命名方式JNIEXPORT void JNICALL Java_com_example_jni_1thread_1demo_JNI_1ThreadActivity_setJNIEnv  (JNIEnv *env, jobject obj){// 保存全局JVM以便在子线程中使用(*env)->GetJavaVM(env, &g_jvm);// 不能直接赋值(g_obj = ojb)g_obj = (*env)->NewGlobalRef(env, obj);}*/JNIEXPORT void JNICALL native_mainThread(JNIEnv *env, /*jclass clazz*/ jobject obj)// 使用jclass和jobject都可以{LOGI("native_mainThread");int i;pthread_t pt[NUMTHREADS];for(i=0; i<NUMTHREADS; i++){// 创建线程,并指明调用的函数,注意只接收一个参数i作为thread_fun的参数,后面会介绍怎么传多个参数pthread_create(&pt[i], NULL, &thread_fun, (void*)i);}}JNIEXPORT void JNICALL native_setJNIEnv(JNIEnv *env, /*jclass obj*/ jobject obj)// 使用jclass和jobject都可以{LOGI("native_setJNIEnv");// 保存全局JVM以便在子线程中使用(*env)->GetJavaVM(env, &g_jvm);// 不能直接赋值(g_obj = ojb)g_obj = (*env)->NewGlobalRef(env, obj);}/*** Table of methods associated with a single class.*/static JNINativeMethod gMethods[] ={{"mainThread", "()V", (void*)native_mainThread },// 绑定:注意千万签名结尾不能加分号!!!!!!{"setJNIEnv", "()V", (void*)native_setJNIEnv },};/** Register several native methods for one class.*/static int registerNativeMethods(JNIEnv* env, const char* className,JNINativeMethod* gMethods, int numMethods){jclass clazz;clazz = (*env)->FindClass(env, className);if (clazz == NULL){return JNI_FALSE;}if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0){return JNI_FALSE;}return JNI_TRUE;}/** Register native methods for all classes we know about.*/static int registerNatives(JNIEnv* env){if (!registerNativeMethods(env, JNIREG_CLASS, gMethods,sizeof(gMethods) / sizeof(gMethods[0])))return JNI_FALSE;return JNI_TRUE;}/** Set some test stuff up.** Returns the JNI version on success, -1 on failure.*/JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){JNIEnv* env = NULL;jint result = -1;if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {LOGE("GetEnv failed!");return -1;}//===========================================assert(env != NULL);if (!registerNatives(env)){// 注册本地方法return -1;}//===========================================/* success -- return valid version number */result = JNI_VERSION_1_4;return result;}

Android.mk文件中的代码:

LOCAL_PATH :=$(call my-dir)include $(CLEAR_VAR)LOCAL_MODULE := JNIThreadLOCAL_SRC_FILES := JNI_Thread.cLOCAL_MODULE_FILENAME := libJNIThread//如果报LOCAL_MODULE_FILENAME的错的话,需要加上这句话LOCAL_LDLIBS := -lloginclude $(BUILD_SHARED_LIBRARY)

如何给线程函数传递多个参数:

涉及多参数传递给线程的,都需要使用结构体将参数封装后,将结构体指针传给线程
定义一个结构体

struct mypara{  var para1;//参数1  var para2;//参数2}


将这个结构体指针,作为void *形参的实际参数传递
struct mypara pstru;pthread_create(&ntid, NULL, thr_fn,& (pstru));


函数中需要定义一个mypara类型的结构指针来引用这个参数
void *thr_fn(void *arg){  mypara *pstru;  pstru = (* struct mypara) arg;  pstru->para1;//参数1  pstru->para2;//参数2}

如何多线程同步通信:

至于多个线程是怎么进行同步通信的,可以参考这篇博文

http://blog.csdn.net/chenghongyue/article/details/8124976



更多相关文章

  1. Android实现关机重启的方法
  2. android屏幕和view的截图
  3. Android(安卓)JNI入门第六篇――C调用Java
  4. android fragment show hide回调
  5. Android(安卓)lifecycle 实战及使用进阶
  6. android scrollview的所有touchevent的顺序
  7. 理解杀进程的实现原理
  8. 转发:bitmap 设置图片尺寸,避免 内存溢出 OutOfMemoryError的优化
  9. Android(安卓)UI 学习 自定义的布局 平滑移动 VelocityTracker()

随机推荐

  1. Android(安卓)Activity界面切换添加动画
  2. TextView显示链接
  3. Android与webview JS 键值编码差异
  4. EditText属性简介
  5. Android(安卓)NKD环境搭建 若干问题.
  6. Android(安卓)Studio快捷键、配置 Androi
  7. Linux Kernel and Android休眠与唤醒
  8. Using Ant to Automate Building Android
  9. Android(安卓)share绘制虚线在手机上显示
  10. 【Android】入门级连接网络示例: 网页浏览