編輯:關於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
在使用Bitmap(位圖)中,我們總是會與BitmapFactory類打交道。今天就來看看BitmapFactory的廬山真面目。首先依舊是看看官網的定義:Creates
本文主要講解MVP開發模式以及具體實例。一、簡介MVP(Model View Presenter)模式是著名的MVC(Model View Controller)模式的一
開篇先介紹幾個放在眼前卻經常忽視的快捷鍵如圖:展現出android Studio超強的搜索能力,提高大工程的開發維護效率。雙擊Shift按鍵效果Ctrl+Shift+N
Buzz桌面安裝好之後,是不會自動將已安裝的手機應用程序圖標添加到桌面上的,需要我們手動添加或拖動應用程序圖標到桌面,下面就讓我們來看看如何將已經安裝的應用