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) {Startthrea DS (threads, iterations);}});} private void Startthreads (int threads, int iterations) {//Javathreads (threads, iterations);//using Java threads to loop posixthreads (Threads, iterations);//use POSIX thread}private void javathreads (int threads, final int iterations) {for (int i = 0; i < THR Eads 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);//Initialize private native void Nativeinit ();//free memory private native void Nativefree ();//Java thread directly calls jniprivate native void nativeworker (int id, int iterations);p rivate static int GetNumber (E Dittext 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:
/* Don't EDIT this file-it are machine generated */#include <jni.h>/* Header for class Com_apress_threads_mainacti Vity */#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 * Sig Nature: () 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_thre Ads_mainactivity_nativeworker (JNIEnv *, Jobject, Jint, jint); #ifdef __cplusplus} #endif #endif
Com_apress_threads_mainactivity.cpp:
#include <stdio.h> #include <unistd.h> #include <pthread.h> #include "Com_apress_threads_ MainActivity.h "#include <android/log.h> #define LOG_TAG" Log from JNI "#define LOGW (a) __android_log_write ( ANDROID_LOG_WARN,LOG_TAG,A)//struct struct Nativeworkerargs for passing pthread parameters {Jint Id;jint iterations;};/ /callback Java method static Jmethodid gonnativemessage = null;static javavm* gVm = NULL; The virtual machine reference, as a global variable static jobject GOBJ = Null;static pthread_mutex_t mutex;//loadlibrary, is automatically called when the global VM reference is obtained 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) {//Initialize mutex if (0! = Pthread_mutex_init ( &mutex, NULL)) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/runtimeexception");//Throw env-> Thrownew (Exceptionclazz, "Unable to init mutex--");} if (NULL = = gObj) {gObj = Env->newglobalref (obj);} Initial Java callback if (NULL = = gonnativemessage) {Jclass clazz = Env->getobjectclass (obj); gonnativemessage = Env->getmethodid (Clazz, "Onnativemessage", "(ljava/lang/string;) V"); if (NULL = = Gonnativemessage) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/runtimeexception");//Throw env-> Thrownew (Exceptionclazz, "Unable to find method--");}}} void Java_com_apress_threads_mainactivity_nativefree (JNIEnv *env, jobject) {//Release global variable if (NULL! = GOBJ) {env-> Deleteglobalref (GOBJ); gObj = NULL;} Release Mutex if (0! = Pthread_mutex_destroy (&mutex)) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/ RuntimeException ");//Throw Env->thrownew (Exceptionclazz," Unable to destroy mutex--");}} NDK thread executes code void Nativeworker (jnienv *env, jobject obj, jint ID, jint iterations) {//lockif (0! = Pthread_mutex_lock (& Mutex) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/runtimeexception");//Throw 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);//Callback JThe Ava method jstring messagestring = ENV->NEWSTRINGUTF (message); Env->callvoidmethod (obj, Gonnativemessage, messagestring); if (NULL! = env->exceptionoccurred ()) {break;} Sleep (1);} Unlockif (0! = Pthread_mutex_unlock (&mutex)) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/ RuntimeException ");//Throw 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 execution method 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);d elete Nativeworkeragrs;gvm->detachcurrentthread ();} Return (void*) 1;} Java calls, starting multiple threads void Java_com_apress_threads_mainactivity_posixthreads (jnienv *env, jobject obj,jint threads, Jint Iterations) {Thread handlerspthread_t* handles = new pthread_t[threads];//start thread for (jint i = 0; i < threads; i++) {//thread argumen tsnativeworkerargs* Nativeworkargs = new Nativeworkerargs (); nativeworkargs->id = I;nativeworkargs->iterations = Iterations;//thread handlerint result = Pthread_create (&handles[i], NULL, Nativeworkerthread, (void*) Nativeworkargs); if (Result! = 0) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/runtimeexception");// Throw Env->thrownew (Exceptionclazz, "Unable to create thread--"); return;}} Thread run result for (jint i = 0; i < threads; i++) {void** result = null;if (0! = Pthread_join (handles[i], result)) {//exception Jclass Exceptionclazz = Env->findclass ("java/lang/runtimeexception");//Throws 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;}}}
Code Download: http://download.csdn.net/detail/hai836045106/7986143
Android NDK programming: Using POSIX multi-threading with mutex mutex synchronization