无法使用GetEnv()获取环境
Failed to get the environment using GetEnv()
我正试图从jni类中为cocos2dx项目调用一些非常简单的java函数。但我一直收到错误在某些重要调用上使用GetEnv((获取环境失败,这会改变整个操作流程。
我正在以以下方式拨打JNI电话
void SaveStringJni(const char *key, const char *value)
{
cocos2d::JniMethodInfo methodInfo;
if (! JniHelper::getStaticMethodInfo(methodInfo, CLASS_NAME, "SaveString", "(Ljava/lang/String;Ljava/lang/String;)V"))
{
return;
}
jstring stringArg = methodInfo.env->NewStringUTF(key);
jstring stringArg2 = methodInfo.env->NewStringUTF(value);
methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, stringArg, stringArg2);
methodInfo.env->DeleteLocalRef(stringArg);
methodInfo.env->DeleteLocalRef(stringArg2);
methodInfo.env->DeleteLocalRef(methodInfo.classID);
}
我使用的是下面给出的cocos2d-x中的JniHelper类。
#include "JniHelper.h"
#include <android/log.h>
#include <string.h>
#if 1
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
#define JAVAVM cocos2d::JniHelper::getJavaVM()
using namespace std;
extern "C"
{
//////////////////////////////////////////////////////////////////////////
// java vm helper function
//////////////////////////////////////////////////////////////////////////
static bool getEnv(JNIEnv **env)
{
bool bRet = false;
do
{
if (JAVAVM->GetEnv((void**)env, JNI_VERSION_1_4) != JNI_OK)
{
LOGD("Failed to get the environment using GetEnv()");
break;
}
if (JAVAVM->AttachCurrentThread(env, 0) < 0)
{
LOGD("Failed to get the environment using AttachCurrentThread()");
break;
}
bRet = true;
} while (0);
return bRet;
}
static jclass getClassID_(const char *className, JNIEnv *env)
{
JNIEnv *pEnv = env;
jclass ret = 0;
do
{
if (! pEnv)
{
if (! getEnv(&pEnv))
{
break;
}
}
ret = pEnv->FindClass(className);
if (! ret)
{
LOGD("Failed to find class of %s", className);
break;
}
} while (0);
return ret;
}
static bool getStaticMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)
{
jmethodID methodID = 0;
JNIEnv *pEnv = 0;
bool bRet = false;
do
{
if (! getEnv(&pEnv))
{
break;
}
jclass classID = getClassID_(className, pEnv);
methodID = pEnv->GetStaticMethodID(classID, methodName, paramCode);
if (! methodID)
{
LOGD("Failed to find static method id of %s", methodName);
break;
}
methodinfo.classID = classID;
methodinfo.env = pEnv;
methodinfo.methodID = methodID;
bRet = true;
} while (0);
return bRet;
}
static bool getMethodInfo_(cocos2d::JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)
{
jmethodID methodID = 0;
JNIEnv *pEnv = 0;
bool bRet = false;
do
{
if (! getEnv(&pEnv))
{
break;
}
jclass classID = getClassID_(className, pEnv);
methodID = pEnv->GetMethodID(classID, methodName, paramCode);
if (! methodID)
{
LOGD("Failed to find method id of %s", methodName);
break;
}
methodinfo.classID = classID;
methodinfo.env = pEnv;
methodinfo.methodID = methodID;
bRet = true;
} while (0);
return bRet;
}
static string jstring2string_(jstring jstr)
{
if (jstr == NULL)
{
return "";
}
JNIEnv *env = 0;
if (! getEnv(&env))
{
return 0;
}
const char* chars = env->GetStringUTFChars(jstr, NULL);
string ret(chars);
env->ReleaseStringUTFChars(jstr, chars);
return ret;
}
}
NS_CC_BEGIN
JavaVM* JniHelper::m_psJavaVM = NULL;
JavaVM* JniHelper::getJavaVM()
{
return m_psJavaVM;
}
void JniHelper::setJavaVM(JavaVM *javaVM)
{
m_psJavaVM = javaVM;
}
string JniHelper::m_externalAssetPath;
const char* JniHelper::getExternalAssetPath() {
return m_externalAssetPath.c_str();
}
void JniHelper::setExternalAssetPath(const char * externalAssetPath) {
m_externalAssetPath = externalAssetPath;
}
jclass JniHelper::getClassID(const char *className, JNIEnv *env)
{
return getClassID_(className, env);
}
bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)
{
return getStaticMethodInfo_(methodinfo, className, methodName, paramCode);
}
bool JniHelper::getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode)
{
return getMethodInfo_(methodinfo, className, methodName, paramCode);
}
string JniHelper::jstring2string(jstring str)
{
return jstring2string_(str);
}
NS_CC_END
这有时有效,但我有时也会遇到上面提到的错误。有人能告诉我怎么解决这个问题吗。
错误是因为我没有从主线程调用函数
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- TCL文件无法获取通过代码设置的环境变量
- 获取通过环境变量访问的文件的位置
- 如何以跨平台方式获取C中的环境变量
- 我想获取用户输入并将其输出到我的 shell 环境中
- 如何获取我的环境的当前区域设置
- 从 Windows 获取 c++ 中的系统环境
- C++cgi脚本获取空的环境变量作为表单的操作
- 从c++中获取shell环境变量
- 如何使用boost库获取系统环境变量
- 在GDB中调试程序时如何获取程序的环境
- 是否有一种方法可以从VS环境之外的MS单元测试框架中获取信息
- 如何在启动时从FastCGI c++二进制文件中获取环境变量
- 如何在OSX中使用c++获取当前用户的语言环境
- 如何在Windows环境下获取主叫用户桌面的绝对路径
- 在VS中以C/ c++编程方式获取Visual Studio环境变量
- 宏从周围环境中获取输入
- 无法使用GetEnv()获取环境