android NDK編程:使用posix多線程與mutex互斥同步
MainActivity.java
package com.apress.threads;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;public class MainActivity extends Activity {private EditText editThreads;private EditText editIterations;private Button btnStart;private TextView tvLog;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);nativeInit();editThreads = (EditText) findViewById(R.id.threads_edit);editIterations = (EditText) findViewById(R.id.iterations_edit);btnStart = (Button) findViewById(R.id.start_button);tvLog = (TextView) findViewById(R.id.log_view);btnStart.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {int threads = getNumber(editThreads, 0);int iterations = getNumber(editIterations, 0);if (threads > 0 && iterations > 0) {startThreads(threads, iterations);}}});}private void startThreads(int threads, int iterations) {// javaThreads(threads, iterations);//使用java的線程來迴圈posixThreads(threads, iterations);// 使用posix線程}private void javaThreads(int threads, final int iterations) {for (int i = 0; i < threads; i++) {final int id = i;new Thread() {@Overridepublic void run() {nativeWorker(id, iterations);super.run();}}.start();}}private void onNativeMessage(final String message) {runOnUiThread(new Runnable() {@Overridepublic void run() {tvLog.append(message);tvLog.append("\n");}});}private native void posixThreads(int threads, int iterations);// 初始化private native void nativeInit();// 釋放記憶體private native void nativeFree();// java線程直接調用jniprivate native void nativeWorker(int id, int iterations);private static int getNumber(EditText editText, int defaultValue) {int value;try {value = Integer.parseInt(editText.getText().toString());} catch (Exception e) {value = defaultValue;}return value;}@Overrideprotected void onDestroy() {nativeFree();super.onDestroy();}static {System.loadLibrary("Threads");}}
com_apress_threads_MainActivity.h:
/* DO NOT EDIT THIS FILE - it is machine generated */#include /* Header for class com_apress_threads_MainActivity */#ifndef _Included_com_apress_threads_MainActivity#define _Included_com_apress_threads_MainActivity#ifdef __cplusplusextern "C" {#endif/* * Class: com_apress_threads_MainActivity * Method: posixThreads * Signature: (II)V */JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_posixThreads (JNIEnv *, jobject, jint, jint);/* * Class: com_apress_threads_MainActivity * Method: nativeInit * Signature: ()V */JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeInit (JNIEnv *, jobject);/* * Class: com_apress_threads_MainActivity * Method: nativeFree * Signature: ()V */JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeFree (JNIEnv *, jobject);/* * Class: com_apress_threads_MainActivity * Method: nativeWorker * Signature: (II)V */JNIEXPORT void JNICALL Java_com_apress_threads_MainActivity_nativeWorker (JNIEnv *, jobject, jint, jint);#ifdef __cplusplus}#endif#endif
com_apress_threads_MainActivity.cpp:
#include #include #include #include "com_apress_threads_MainActivity.h"#include #define LOG_TAG "LOG FROM JNI"#define LOGW(a) __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a)//傳遞pthread參數用的結構體struct NativeWorkerArgs {jint id;jint iterations;};//回調java的方法static jmethodID gOnNativeMessage = NULL;static JavaVM* gVm = NULL; //虛擬機器引用,作為全域變數static jobject gObj = NULL;static pthread_mutex_t mutex;//loadLibrary的時候自動調用,在這裡獲得全域vm引用jint JNI_OnLoad(JavaVM* vm, void* reserved) {gVm = vm;LOGW("JNI_OnLoad");return JNI_VERSION_1_4;}void Java_com_apress_threads_MainActivity_nativeInit(JNIEnv *env, jobject obj) {//初始化互斥量if (0 != pthread_mutex_init(&mutex, NULL)) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to init mutex--");}if (NULL == gObj) {gObj = env->NewGlobalRef(obj);}//初始java回調if (NULL == gOnNativeMessage) {jclass clazz = env->GetObjectClass(obj);gOnNativeMessage = env->GetMethodID(clazz, "onNativeMessage","(Ljava/lang/String;)V");if (NULL == gOnNativeMessage) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to find method--");}}}void Java_com_apress_threads_MainActivity_nativeFree(JNIEnv *env, jobject) {//釋放全域變數if (NULL != gObj) {env->DeleteGlobalRef(gObj);gObj = NULL;}//釋放互斥量if (0 != pthread_mutex_destroy(&mutex)) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to destroy mutex--");}}//ndk線程執行的代碼void nativeWorker(JNIEnv *env, jobject obj, jint id, jint iterations) {//lockif (0 != pthread_mutex_lock(&mutex)) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to lock mutex--");return;}for (jint i = 0; i < iterations; i++) {char message[26];sprintf(message, "Worker %d:Iteration %d", id, i);//回調java方法jstring messageString = env->NewStringUTF(message);env->CallVoidMethod(obj, gOnNativeMessage, messageString);if (NULL != env->ExceptionOccurred()) {break;}sleep(1);}//unlockif (0 != pthread_mutex_unlock(&mutex)) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to unlock mutex--");}}void Java_com_apress_threads_MainActivity_nativeWorker(JNIEnv *env, jobject obj,jint id, jint iterations) {nativeWorker(env, obj, id, iterations);}//pthread執行的方法static void* nativeWorkerThread(void* args) {JNIEnv* env = NULL;if (0 == gVm->AttachCurrentThread(&env, NULL)) {NativeWorkerArgs* nativeWorkerAgrs = (NativeWorkerArgs*) args;//nativeWorker(env, gObj, nativeWorkerAgrs->id,nativeWorkerAgrs->iterations);delete nativeWorkerAgrs;gVm->DetachCurrentThread();}return (void*) 1;}//java調用的,啟動多個線程void Java_com_apress_threads_MainActivity_posixThreads(JNIEnv *env, jobject obj,jint threads, jint iterations) {//thread handlerspthread_t* handles = new pthread_t[threads];//啟動線程for (jint i = 0; i < threads; i++) {//thread argumentsNativeWorkerArgs* nativeWorkArgs = new NativeWorkerArgs();nativeWorkArgs->id = i;nativeWorkArgs->iterations = iterations;//thread handlerint result = pthread_create(&handles[i], NULL, nativeWorkerThread,(void*) nativeWorkArgs);if (result != 0) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to create thread--");return;}}//線程運行結果for (jint i = 0; i < threads; i++) {void** result = NULL;if (0 != pthread_join(handles[i], result)) {//異常jclass exceptionClazz = env->FindClass("java/lang/RuntimeException");//拋出env->ThrowNew(exceptionClazz, "Unable to join thread--");} else {char message[26];sprintf(message, "Worker %d:return %d", i, result);jstring messageString = env->NewStringUTF(message);env->CallVoidMethod(obj, gOnNativeMessage, messageString);if (NULL != env->ExceptionOccurred()) {return;}}}}
下載: http://download.csdn.net/detail/hai836045106/7986143