Jni FindClass返回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, "", "()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;"); } 

function initializeJniPointers()粉碎在线StatusLine :: GetStatusCode = GetJniEnv() – > GetMethodID(); 因为StatusLine :: Class为NULL。 但! 我注意到:如果我在项目的一些java文件中写这个StatusLine l = new StatuLine(){…}

函数粉碎了ByteArrayOutputStream :: Constructor,因为ByteArrayOutputStream :: Class为NULL,如果我在java中创建ByteArrayOutputStream的对象,函数会更进一步到下一个对象等…我注意到:如果我只声明一个变量ByteArrayOutputStream ,findClass将返回NULL。

有人可以解释一下该怎么办? BTW我使用Android 2.3.5设备三星GT-S5363,我尝试了其他Android(老人)和设备的转换,它工作正常。

基本上,如果您要求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这样的系统类的系统类加载器。

另一种对我有用的技术是在本机方法调用之前(例如在AsyncTask doInBackground()中)实例化所需类(Java端)的对象。