当前位置: 首页 > news >正文

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代码中调用:

 

 

显示结果如下:

 

 

 工程整个文件结构:

 

 其他信息:

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/MMLoveMeMM/articles/3750099.html

相关文章:

  • 铁大课表 详细设计说明书
  • 结合FireBreath在Chrome/FireFox的多进程模式下崩溃一例
  • Java多线程之Wait()和Notify()
  • [java面试]宇信易诚 广州分公司 java笔试题目回忆录
  • 忘记scott密码解决
  • 采集/自动登录啊都可以用这两个方法实现 asp.net
  • windows phone随笔
  • [CLR via C#]11. 事件
  • Welcome to Swift (苹果官方Swift文档初译与注解九)---58~62页(第二章)
  • 高级mask应用
  • 义隆单片机学习笔记之(四) 编程及烧录
  • ASP.NET MD5加密
  • topcoder SRM 618 DIV2 MovingRooksDiv2
  • 微信公众号自定义菜单与回车
  • 协议分析-迅雷镜象服务器下载
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • AWS实战 - 利用IAM对S3做访问控制
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • java 多线程基础, 我觉得还是有必要看看的
  • java小心机(3)| 浅析finalize()
  • js继承的实现方法
  • leetcode386. Lexicographical Numbers
  • Python学习笔记 字符串拼接
  • Selenium实战教程系列(二)---元素定位
  • 仿天猫超市收藏抛物线动画工具库
  • 简单基于spring的redis配置(单机和集群模式)
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 盘点那些不知名却常用的 Git 操作
  • 前端学习笔记之观察者模式
  • 世界编程语言排行榜2008年06月(ActionScript 挺进20强)
  • 问:在指定的JSON数据中(最外层是数组)根据指定条件拿到匹配到的结果
  • 项目实战-Api的解决方案
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 移动端高清、多屏适配方案
  • # Apache SeaTunnel 究竟是什么?
  • #Linux(帮助手册)
  • #Lua:Lua调用C++生成的DLL库
  • $ git push -u origin master 推送到远程库出错
  • (Java数据结构)ArrayList
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (附源码)php投票系统 毕业设计 121500
  • (生成器)yield与(迭代器)generator
  • (一)WLAN定义和基本架构转
  • (转)Linq学习笔记
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET/C# 使用 SpanT 为字符串处理提升性能
  • .net分布式压力测试工具(Beetle.DT)
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET框架设计—常被忽视的C#设计技巧