Jni FindClass returns NULL
Jni FindClass returns NULL
我在头文件中得到了c++结构
struct StatusLine
{
static jclass Class; // Lorg/apache/http/StatusLine;
static jmethodID GetStatusCode; // ()I
};
struct ByteArrayOutputStream
{
static jclass Class; // Ljava/io/ByteArrayOutputStream;
static jmethodID Constructor; // ()V
static jmethodID Close; // ()V
static jmethodID ToByteArray; // ()[B
};
struct HttpEntity
{
static jclass Class; // Lorg/apache/http/HttpEntity;
static jmethodID WriteTo; // (Ljava/io/OutputStream;)V
static jmethodID GetContent; // ()Ljava/io/InputStream;
};
并且cpp文件是
#define JAVA_STATUS_LINE_CLASS "org/apache/http/StatusLine"
#define JAVA_HTTP_ENTITY_CLASS "org/apache/http/HttpEntity"
#define JAVA_BYTE_ARRAY_OUTPUT_STREAM_CLASS "java/io/ByteArrayOutputStream"
jclass StatusLine::Class = 0;
jmethodID StatusLine::GetStatusCode = 0;
jclass ByteArrayOutputStream::Class = 0;
jmethodID ByteArrayOutputStream::Constructor = 0;
jmethodID ByteArrayOutputStream::Close = 0;
jmethodID ByteArrayOutputStream::ToByteArray = 0;
jclass HttpEntity::Class = 0;
jmethodID HttpEntity::WriteTo = 0;
jmethodID HttpEntity::GetContent = 0;
void initializeJniPointers()
{
StatusLine::Class = GetJniEnv()->FindClass(JAVA_STATUS_LINE_CLASS);
StatusLine::GetStatusCode = GetJniEnv()->GetMethodID(StatusLine::Class, "getStatusCode", "()I");
ByteArrayOutputStream::Class = GetJniEnv()->FindClass(JAVA_BYTE_ARRAY_OUTPUT_STREAM_CLASS);
ByteArrayOutputStream::Constructor = GetJniEnv()->GetMethodID(ByteArrayOutputStream::Class, "<init>", "()V");
ByteArrayOutputStream::Close = GetJniEnv()->GetMethodID(ByteArrayOutputStream::Class, "close", "()V");
ByteArrayOutputStream::ToByteArray = GetJniEnv()->GetMethodID(ByteArrayOutputStream::Class, "toByteArray", "()[B");
HttpEntity::Class = GetJniEnv()->FindClass(JAVA_HTTP_ENTITY_CLASS);
HttpEntity::WriteTo = GetJniEnv()->GetMethodID(HttpEntity::Class, "writeTo", "(Ljava/io/OutputStream;)V");
HttpEntity::GetContent = GetJniEnv()->GetMethodID(HttpEntity::Class, "getContent", "()Ljava/io/InputStream;");
}
函数initializeJniPointers()在行StatusLine::GetStatusCode=GetJniEnv()->GetMethodID()上进行压缩;因为StatusLine::Class为NULL。但是我注意到:如果我把它写在项目的某个java文件中StatusLine l=新StatusLine(){。。。}
函数对ByteArrayOutputStream::Constructor进行压缩,因为ByteArrayOutput Stream::Class为NULL,如果我在java中创建ByteArrayOutputStream的对象,函数将进一步访问下一个对象,等等。我注意到:如果我只声明ByteArrayOut Stream的变量,findClass将返回NULL。
有人能给我解释一下该怎么办吗?顺便说一句,我使用安卓2.3.5设备三星GT-S5363,我尝试了安卓(老年人)和设备的其他版本,它工作得很好。
基本上,如果您请求FindClass
的线程不是主线程,并且在您的线程系统中没有构建java类ID的映射,就会发生这种情况。
检查一下,您可能必须首先在主线程中询问FindClass
(当JNI加载或在其他地方加载时),然后才能在任何线程中这样做。
http://discuss.cocos2d-x.org/t/jni-findclass-cannot-find-a-class-if-its-called-by-a-new-pthread/1873/4
也尝试一下,这对我很有效:https://svn.apache.org/repos/asf/mesos/branches/0.10.x/src/java/jni/convert.cpp
解决方案(取自上面的链接)是从JNI_OnLoad
中的应用程序中找到一个Java类加载器,并要求他从任何线程中找到类。否则,在调用env->FindClass
之后,JNI可以回退到只加载像String
这样的系统类的系统类加载器。
另一种对我有用的技术是在本机方法调用之前实例化所需类的对象,Java端(例如,在AsyncTask doInBackground()中)。
- gdk_screen_get_default() returns null
- FindClass returns null
- SDL_ttf TTF_OpenFont returns NULL
- PKCS7_sign returns null
- C++ CreateWindowEx returns NULL
- wglGetProcAddress returns NULL
- cvCaptureFromCAM(CV_CAP_ANY) returns NULL
- gethostbyaddr() returns null
- glfwCreateWindow returns NULL
- CreateWindowEx returns NULL
- CreateFileMapping() returns null
- C++ LoadLibrary Returns Null
- Jni FindClass returns NULL
- SDL/TTF: TTF_RenderText_Blended_Wrapped returns NULL
- osg::GraphicsContext::WindowingSystemInterface returns null
- JNI- FindClass returns null
- VFW: AVIStreamGetFrameOpen() returns NULL
- engOpen returns Null
- avformat_alloc_context returns null
- TinyXML2 returns Null?