編輯:關於Android編程
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;
@Override
protected 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() {
@Override
public 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() {
@Override
public void run() {
nativeWorker(id, iterations);
super.run();
}
}.start();
}
}
private void onNativeMessage(final String message) {
runOnUiThread(new Runnable() {
@Override
public 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線程直接調用jni
private 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;
}
@Override
protected 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 __cplusplus extern "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) { //lock if (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); } //unlock if (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 handlers pthread_t* handles = new pthread_t[threads]; //啟動線程 for (jint i = 0; i < threads; i++) { //thread arguments NativeWorkerArgs* nativeWorkArgs = new NativeWorkerArgs(); nativeWorkArgs->id = i; nativeWorkArgs->iterations = iterations; //thread handler int 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
Android 位圖(一) BitmapFactory類
在使用Bitmap(位圖)中,我們總是會與BitmapFactory類打交道。今天就來看看BitmapFactory的廬山真面目。首先依舊是看看官網的定義:Creates
詳解Android MVP開發模式
本文主要講解MVP開發模式以及具體實例。一、簡介MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一
學習Android Studio開發工具之Activity2(&Fragment)
開篇先介紹幾個放在眼前卻經常忽視的快捷鍵如圖:展現出android Studio超強的搜索能力,提高大工程的開發維護效率。雙擊Shift按鍵效果Ctrl+Shift+N
Buzz桌面教程-添加應用程序圖標到桌面
Buzz桌面安裝好之後,是不會自動將已安裝的手機應用程序圖標添加到桌面上的,需要我們手動添加或拖動應用程序圖標到桌面,下面就讓我們來看看如何將已經安裝的應用