本文介绍了Jni FindClass返回NULL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在头文件中得到了c ++结构,

I got c++ structs in header file,

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 = new StatuLine()
{
...
}

function initializeJniPointers() crushes on line StatusLine::GetStatusCode = GetJniEnv()->GetMethodID(); because StatusLine::Class is NULL. But! I notice that:If I write this in some java file of the project StatusLine l = new StatuLine() { ... }

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

Function crushes on ByteArrayOutputStream::Constructor because ByteArrayOutputStream::Class is NULL, if I create an object of ByteArrayOutputStream in java, function will go further to the next object, etc... I notice that: If I just declare a variable of ByteArrayOutputStream, findClass will return NULL.

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

Could someone explain me what to do? BTW I use Android 2.3.5 device Samsung GT-S5363, I tried other vertions of android (elder) and devices and it works fine.

推荐答案

基本上,如果您要求FindClass的线程不是主线程并且您的线程系统中没有构建java类ID的映射。

Basically this can occur if the thread where you ask FindClass is not the main thread and in your thread system does not build a map of java class IDs.

检查一下,可能你必须先在主线程中询问FindClass(当JNI加载或其他地方时),然后你会有能够在任何线程中做到这一点。

Check this out, probably you have to ask FindClass first in the main thread (when JNI loads or somewhere else), and then you will have ability to do that in any thread.

也试试这个,这对我有用:

Also try this out, this worked for me:https://svn.apache.org/repos/asf/mesos/branches/0.10.x/src/java/jni/convert.cpp

解决方案(取自上面的链接)是从您的应用程序中找到Java类加载器在JNI_OnLoad并要求他从任何线程找到课程。否则,在调用env-> FindClass之后,JNI可以回退到系统类加载器,它只加载像String这样的系统类。

The solution (taken from link above) is finding a Java class loader from your app in JNI_OnLoad and ask him to find class then from any thread. Otherwise, after calling env->FindClass JNI can fall back to the system class loader which loads only system classes like String.

这篇关于Jni FindClass返回NULL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-17 20:35