android JNI基本库(jsting转string和C多线程调用java方法的说明)

来源:互联网 发布:微信陌陌定位软件 编辑:程序博客网 时间:2024/06/01 09:32


1.JNI开发时经常需要使用到jstring和string的转换,还有C++多线程中使用JNIEnv,因此特意写了这个类,方便以后的开发使用。

注意:  如果要使用打印日志的LOGI和LOGE需要在mk文件中链接log库

LOCAL_LDLIBS := -llog



2.在C++创建的多线程中使用JNIEnv中的findclass方法会出现找不到类库的问题,是因为只能在主线程中使用findclass

去查找类库,因此如果需要在c线程中调用java中的方法的话 需要在主线程中使用GetMethodID获取出相应的JAVA方法

的ID,然后使用Attach后的JNIEnv调用java方法。LOCAL_LDLIBS := -llog


JNIUtil.h 代码

#ifndef JNI_UTIL_H#define JNI_UTIL_H#include <jni.h>#include <android/log.h>#include <string>using namespace std;#define LOG_TAG "JNI_LOG"#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)class JNIUtil{public:/* 注意Init和CleanUp必须在主线程中执行*/static void Init(JNIEnv* env);static void CleanUp(JNIEnv* env);public:JNIUtil();~JNIUtil();JNIEnv* GetJNIEnv();string Jstring2String(jstring jstr);jstring String2Jstring(const char* str);private:static jclass m_strClass;static jmethodID m_ctorID;static jmethodID m_getByteID;void Detach();static JavaVM* m_sJVM;public:bool m_bAttach;};#endif


JNIUtil.cpp 代码

#include <jni.h>#include <stdlib.h>#include "JNIUtil.h"JavaVM* JNIUtil::m_sJVM = NULL;jclass JNIUtil::m_strClass = NULL;jmethodID JNIUtil::m_ctorID = 0;jmethodID JNIUtil::m_getByteID = 0;void JNIUtil::Init(JNIEnv* env){env->GetJavaVM(&m_sJVM);jclass tmp = env->FindClass("java/lang/String");m_strClass = (jclass)env->NewGlobalRef(tmp);m_ctorID = env->GetMethodID(m_strClass, "<init>","([BLjava/lang/String;)V");m_getByteID = env->GetMethodID(m_strClass, "getBytes","(Ljava/lang/String;)[B");}void JNIUtil::CleanUp(JNIEnv* env){env->DeleteGlobalRef(m_strClass);m_sJVM = NULL;m_strClass = NULL;m_getByteID =0;m_ctorID = 0;}JNIUtil::JNIUtil() :m_bAttach(false){}JNIUtil::~JNIUtil(){Detach();}JNIEnv* JNIUtil::GetJNIEnv(){if (m_sJVM == NULL)return NULL;int status = 0;JNIEnv *env = NULL;status = m_sJVM->GetEnv((void**) &env, JNI_VERSION_1_4);if (status < 0){status = m_sJVM->AttachCurrentThread(&env, NULL);if (status < 0){return NULL;}m_bAttach = true;}return env;}void JNIUtil::Detach(){if (m_bAttach){m_sJVM->DetachCurrentThread();m_bAttach = false;}}string JNIUtil::Jstring2String(jstring jstr){JNIEnv *env = NULL;env = GetJNIEnv();char* rtn = NULL;jstring strencode = env->NewStringUTF("utf-8");jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, m_getByteID, strencode);jsize alen = env->GetArrayLength(barr);jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);if (alen > 0){rtn = new char[alen+1];memcpy(rtn, ba, alen);rtn[alen] = 0;}env->ReleaseByteArrayElements(barr, ba, 0);string strRet(rtn);delete[] rtn;return strRet;}//char* to jstringjstring JNIUtil::String2Jstring(const char* pat){JNIEnv *env = NULL;env = GetJNIEnv();jbyteArray bytes = env->NewByteArray(strlen(pat));env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*) pat);jstring encoding = env->NewStringUTF("utf-8");return (jstring)env->NewObject(m_strClass, m_ctorID, bytes, encoding);}






0 0