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


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 
#include 
#include 
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 
#include 
#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, "",
				"([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 jstring
jstring 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);
}







你可能感兴趣的:(安卓JNI)