android jni framework,Android Framework层和Native层经过JNI实现通讯

本文介绍了如何通过JNI在C++中创建并管理线程,实现Java与C++的跨线程通信。作者详细展示了如何获取JNIEnv、注册native方法,并演示了native_thread_exec函数的工作流程以及native_thread_start和native_thread_stop的使用。
摘要由CSDN通过智能技术生成

#include "com_xxx_android2native_JniManager.h"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define TAG "JniNative"

#define LOGE(TAG,...) __android_log_print(ANDROID_LOG_INFO,TAG,__VA_ARGS__)

JavaVM *gJavaVM;

jobject gJavaObj;

int volatile gIsThreadStop = 0;

static void* native_thread_exec(void *arg)

{

LOGE(TAG,"nativeThreadExec");

JNIEnv *env;

//从全局的JavaVM中获取到环境变量

gJavaVM->AttachCurrentThread(&env,NULL);

//get Java class by classPath

//获取Java层对应的类

jclass thiz = env->GetObjectClass(gJavaObj);

//get Java method from thiz

//获取Java层被回调的函数

jmethodID nativeCallback = env->GetMethodID(thiz,"callByJni","(I)V");

int count = 0;

//线程循环

while(!gIsThreadStop)

{

sleep(2);

//跨线程回调Java层函数

env->CallVoidMethod(gJavaObj,nativeCallback,count++);

}

gJavaVM->DetachCurrentThread();

LOGE(TAG,"thread stoped");

return ((void *)0);

}

JNIEXPORT void JNICALL Java_com_xxx_android2native_JniManager_nativeThreadStart

(JNIEnv * env, jobject object)

{

LOGE(TAG,"native_thread_start");

gIsThreadStop = 0;

pthread_t id;

//经过pthread库建立线程

if(pthread_create(&id,NULL,native_thread_exec,NULL)!=0)

{

LOGE(TAG,"native thread create fail");

return;

}

LOGE(TAG,"native thread creat success");

}

JNIEXPORT void JNICALL Java_com_xxx_android2native_JniManager_nativeThreadStop

(JNIEnv * env, jobject object)

{

gIsThreadStop = 1;

LOGE(TAG,"native_thread_stop");

}

JNIEXPORT void JNICALL Java_com_xxx_android2native_JniManager_openJni

(JNIEnv * env, jobject object)

{

LOGE(TAG, "Java_com_xxx_android2native_JniManager_openJni");

//注意,直接经过定义全局的JNIEnv和Object变量,在此保存env和object的值是不能够在线程中使用的

//线程不容许共用env环境变量,可是JavaVM指针是整个jvm共用的,因此能够经过下面

//的方法保存JavaVM指针,在线程中使用

env->GetJavaVM(&gJavaVM);

//同理,jobject变量也不容许在线程中共用,所以须要建立全局的jobject对象在线程

//中访问该对象

gJavaObj = env->NewGlobalRef(object);

gIsThreadStop = 0;

}

/*须要注册的函数列表,放在JNINativeMethod 类型的数组中,

之后若是须要增长函数,只需在这里添加就好了

参数:

1.java中用native关键字声明的函数名

2.签名(传进来参数类型和返回值类型的说明)

3.C/C++中对应函数的函数名(地址)

*/

static JNINativeMethod methods[] =

{

{ "openJni", "()V",(void*) Java_com_xxx_android2native_JniManager_openJni },

{ "nativeThreadStart", "()V",(void*) Java_com_xxx_android2native_JniManager_nativeThreadStart },

{ "nativeThreadStop", "()V",(void*) Java_com_xxx_android2native_JniManager_nativeThreadStop },

};

//此函数经过调用RegisterNatives方法来注册咱们的函数

static int registerNativeMethods(JNIEnv* env, const char* className,

JNINativeMethod* getMethods, int methodsNum) {

jclass clazz;

//找到声明native方法的类

clazz = env->FindClass(className);

if (clazz == NULL) {

return JNI_FALSE;

}

//注册函数 参数:java类 所要注册的函数数组 注册函数的个数

if (env->RegisterNatives(clazz, getMethods, methodsNum) < 0) {

return JNI_FALSE;

}

return JNI_TRUE;

}

static int registerNatives(JNIEnv* env) {

//指定类的路径,经过FindClass 方法来找到对应的类

const char* className = "com/xxx/android2native/JniManager";

return registerNativeMethods(env, className, methods,

sizeof(methods) / sizeof(methods[0]));

}

//回调函数

JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv* env = NULL;

//获取JNIEnv

if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) {

return -1;

}

assert(env != NULL);

//注册函数 registerNatives ->registerNativeMethods ->env->RegisterNatives

if (!registerNatives(env)) {

return -1;

}

//返回jni 的版本

return JNI_VERSION_1_6;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值