我在头文件中有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 =新的StatuLine()
{
...
}

函数在ByteArrayOutputStream::Constructor上崩溃,因为ByteArrayOutputStream::Class为NULL,如果我在Java中创建ByteArrayOutputStream的对象,则函数将进一步移至下一个对象,以此类推。 ,findClass将返回NULL。

有人可以解释我该怎么做吗?顺便说一句,我使用的是Android 2.3.5设备Samsung 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这样的系统类。

10-06 13:41