Android NDK JNI C++ <13> pthread多线程

这一篇将初步介绍NDK开发中多线程方面相关操作,具体步骤如下:

多线程采用 POSIX 的pthread方式实现.

<1> : 新建一个Android工程 androidpthreadjnidemo.然后在工程目录新建jni文件夹,在src下新建一个org的package,然后再这个package包下新建一个pthreadClass.java,pthreadClass的类的实现如下:

看来virtual box的剪贴板老是有问题.切换到host这边来.

 

<2> : 在jni目录下新建onload.h,onload.cpp,pthreadClass.cpp,其中这个pthreadClass.cpp和pthreadClass.java文件没有文件上的牵连关系,也可以命名为sb.cpp,这里只需要注意,如果是按照c++的方式实现程序代码,

那么JNIEnv* env这个用,比如:

C代码:
(*env)->FindClass("org/pthreadClass");
而C++代码:
env->FindClass("org/pthreadClass");

具体原因可以自行查找,大致思想是jni已经做了C和C++的区分,所以要注意他们的书写方式.

我这里是使用C++的,所以全部采用下面的那种书写方式.

<3> : onload.cpp,onload.h是通用的,可以在以后工程中统一都添加进来.

onload.cpp:

#include "onload.h"
#include <android/log.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#define TAG "jni_thread"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__))

extern int register_android_pthread_jni_demo(JNIEnv* env);


JavaVM* mEnv;

JavaVM* getJNIVM(){

    JavaVM* env=NULL;
    if(mEnv->GetEnv((void**)&env,JNI_VERSION_1_4)){
        return NULL;
    }
    return env;

}
int jniRegisterNativeMethods(JNIEnv* env,const char* classname,const JNINativeMethod* gMethods,int numMethods){

    jclass classz;
    classz=env->FindClass(classname);

    if(classz==NULL){
        return JNI_ERR;
    }
    if(env->RegisterNatives(classz,gMethods,numMethods)<0){
        return JNI_ERR;
    }

    return JNI_OK;

}
int jniThrowExeption(JNIEnv *env,const char* classname){

    jclass classz;
    classz=env->FindClass(classname);
    if(classz==NULL){
        return JNI_ERR;
    }
    return JNI_OK;

}
jint JNI_OnLoad(JavaVM *vm, void *reserved){

    JNIEnv* env=NULL;
    jint result=JNI_ERR;
    mEnv=vm;

    if(vm->GetEnv((void**)&env,JNI_VERSION_1_4)!=JNI_OK){
        return result;
    }

    if(register_android_pthread_jni_demo(env)!=JNI_OK){
        goto end;
        //will not continue register others native methods
        //goto end at once
    }

    return JNI_VERSION_1_4;

end:
    return result;

}


onload.h:

#include<jni.h>
#ifndef _ON_LOAD_HEADER_H__
#define _ON_LOAD_HEADER_H__

JavaVM* getJNIVM();
int jniRegisterNativeMethods(JNIEnv* env,const char* classname,const JNINativeMethod* gMethods,int numMethods);
int jniThrowExeption(JNIEnv *env,const char* classname);
jint JNI_OnLoad(JavaVM *vm, void *reserved);

#endif


pthreadClass.cpp:

#include <jni.h>
#include <android/log.h>
#include <pthread.h>

#include "onload.h"

#define TAG "jni_thread"

#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN,TAG,__VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR,TAG,__VA_ARGS__))
#define NUMT 5
#define JAVA_CLASS_PATH "org/pthreadClass"
namespace android{

    void native_init(){

        LOGI("native init .");

    }


    void* fun_in_thread(void* arg){
        LOGI("enter in fun_in_thread !");
    }


    void main_pThread(){
        LOGI("MAIN THREAD");

        pthread_t pt[NUMT];
        int i;

        for(i=0;i<NUMT;i++){
            pthread_create(&pt[i],NULL,&fun_in_thread,(void*)i);
        }
    }

}

using namespace android;

JNINativeMethod mNativeMethods[]={
    {
        "nativeinit","()V",(void*)native_init
    },
    {
        "mainthread","()V",(void*)main_pThread
    }
};

int register_android_pthread_jni_demo(JNIEnv* env){

    return jniRegisterNativeMethods(env,JAVA_CLASS_PATH,mNativeMethods,sizeof(mNativeMethods)/sizeof(mNativeMethods[0]));

}

要实现多线程,必须要包含<pthread.h>头文件,实现创建新的线程的方式如下:

pthread_create(&pt[i],NULL,&fun_in_thread,(void*)i);
参数说明:
第一个参数为指向线程标识符的指针。 

第二个参数用来设置线程属性。 

第三个参数是线程运行函数的起始地址。 

最后一个参数是运行函数的参数

可以参考:https://publib.boulder.ibm.com/iseries/v5r1/ic2924/index.htm?info/apis/users_14.htm
上面的程序实现了连续创建5个线程.

 

Android.mk文件:

LOCAL_PATH    :=$(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE    := threadlib

LOCAL_SRC_FILES    := onload.cpp pthreadClass.cpp

LOCAL_SHARED_LIBRARY := libnativehelper liblog
#下面一句cflags可以不需要
LOCAL_CFLAGS := -llog -lpthread
#添加log的
LOCAL_LDLIBS    :=-llog

include $(BUILD_SHARED_LIBRARY)


Android java代码中调用:

 

 

显示结果如下:

 

 

 工程整个文件结构:

 

 其他信息:

 

 

 

 

 

 

 

 

 

posted @ 2014-05-24 17:18  MMLoveMeMM  阅读(1914)  评论(0编辑  收藏  举报