NDK 5 使用POSIX線程

來源:互聯網
上載者:User

Java中使用線程特別簡單,實現Runnable介面 或者 繼承Thread.

NDK中使用線程可以在Activity中直接調用java線程,也可以通過JNI啟動線程,這個線程源於POSIX中的線程庫。


需要使用POSIX中pthread

標頭檔<pthread.h>


如果啟動了Posix線程,是無法與Android Java層互動的,主要是因為POSIX線程中無法直接調用JNIEnv  。
因此我們需要先把native thread與JVM關聯上,這樣既可獲得JNIEnv。沒有JNIEnv是無法回調JAVA層的方法。


編寫一個Activity 只是列印一個語句Toast


public class MainActivity extends Activity {static {System.loadLibrary("ndk-thread");}public static MainActivity instance;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.start).setOnClickListener(new OnClickListener() {public void onClick(View arg0) {JNI.startThreadJNI(); //JNI Native 方法,啟動線程}});instance = this;}public void showMsg(final String msg) {Log.d("showMsg","msg:" + msg);MainActivity.instance.runOnUiThread(new Runnable(){@Overridepublic void run() {Toast.makeText(instance, msg, Toast.LENGTH_SHORT).show(); //回調彈出訊息}});}}


JNI.java

public class JNI { public JNI() { } public native static void startThreadJNI();}

建立一個Callback.java 用來回調Activity的showMsg方法

public class Callback {public void setMsg(String msg) {MainActivity.instance.showMsg(msg);}public Callback() {}}


在JNI_OnLoad方法中 我們能擷取到JVM對象,這個方法是有架構自動執行的。在JNI.h標頭檔中有原型。

JavaVM* jvm1 = NULL;jobject obj1 = NULL;jmethodID mid1 = NULL;jint JNI_OnLoad (JavaVM* vm, void* reserved){jvm1 = vm;return JNI_VERSION_1_4;}void *run_task(void *args) { //線程需要執行的東西JNIEnv* env = NULL;    int n = (*jvm1)->AttachCurrentThread(jvm1,&env, NULL); //從jvm中擷取到JNIEnv    if (n == 0) {        jstring msg = (*env)->NewStringUTF(env,"Yes Thread Running.");        (*env)->CallVoidMethod(env, obj1, mid1, msg); //回調JAVA層Callback類中的方法        (*env)->DeleteGlobalRef(env,obj1); //刪除引用    (*jvm1)->DetachCurrentThread(jvm1); //這個一定要調用,否則報錯,意在取消線程與jvm關聯    }    LOGI("44");}void init_instance(JNIEnv *env) { LOGI("instance."); jclass jz1 = (*env)->FindClass(env,"com/birds/android/ndk/thread1/Callback"); jmethodID mid = (*env)->GetMethodID(env,jz1,"<init>","()V"); jobject myobj = (*env)->NewObject(env,jz1,mid);          obj1 = (*env)->NewGlobalRef(env,myobj); LOGI("OK Instance Done."); mid1 = (*env)->GetMethodID(env, jz1, "setMsg", "(Ljava/lang/String;)V");}






編寫JNI層代碼。直接寫C代碼

JNIEXPORT void JNICALL Java_com_birds_android_ndk_thread1_JNI_startThreadJNI  (JNIEnv *env, jclass jclas) {    init_instance(env);//主要是準備一些對象執行個體化,Callback執行個體化    pthread_t thread1;        int n = pthread_create(&thread1,NULL,run_task,NULL);//啟動線程,調用run_task方法        if (n != 0) {           //線程建立失敗    jclass exceptionClazz = (*env)->FindClass(env,    "java/lang/RuntimeException");        (*env)->ThrowNew(env,exceptionClazz, "create thread error.");    }}













聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.