JNI - 由JNI自主调用Java方法

时间:2011-10-25 09:19:41

标签: java android java-native-interface wrapper cocos2d-x

这是我关于stackoverflow的第一个问题,我的英语不是最好的。我请求你理解:)

我尝试通过JNI调用静态方法,但我无法捕获JNIEnv。这个项目是在Android平台上运行的,使用eclipse,我无法调试。

我正在使用的代码是:

void MyCClass::myCMethod()
{
    int status;
    JNIEnv *env;
    bool isAttached = false;

    status = gJavaVM->GetEnv((void **) &env, NULL);  // CRASH HERE
    if(status < 0) {
        status = gJavaVM->AttachCurrentThread(&env, NULL);
        if(status < 0) {
            return;
        }
        isAttached = true;
    }

    if(env==NULL) {
        return;
    }

    jclass handlerClass = env->FindClass("com/package/javaClass");

    if(handlerClass==NULL) {
        return;
    }

    jmethodID mid = env->GetMethodID(handlerClass, "TestCall", "()V");
     if (mid == NULL) {
         return;
     }

     env->CallVoidMethod(handlerClass, mid);

}

“status = gJavaVM-&gt; GetEnv((void **)&amp; env,NULL); // CRASH HERE”中的应用程序混乱“

有谁知道如何独立地从C运行Java方法?我想要的是他在任何时候调用Java方法的C。我能够调用方法的唯一方法是从java调用C方法并通过此方法,一旦我们收到JNIEnv参数,就调用Java方法。

。 。

好的......我发现了解决方案:)

解决方案是创建一个单独的类,如:

或者Controller.h

#include <string>
#include <jni.h>

using namespace std;

class Controller {

  public:
    ~Controller() {};
    static Controller* Instance();
    JNIEnv *env;
    jobject obj;

    bool running;

  private:
    Controller() {};

};

Controller.cpp

#include "Controller.h"

Controller* Controller::Instance() {
    static Controller instance;
    return &instance;
}

然后在完成它的类中,必须将init()声明为OnLoad方法()并使用类Controller对象来保存JNIEnv类型的“env”。

extern "C" {
        JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
        {
            cocos2d::CCLog("TESTE LOAD APPLICATION");

            jint result = -1;

            if (vm->GetEnv((void**) &Controller::Instance()->env, JNI_VERSION_1_4) != JNI_OK) {
                    cocos2d::CCLog("TESTE FAIL LOAD");
                    return result;
                }
                cocos2d::CCLog("Could not retrieve the env!");
                //test(env);

                cocos2d::CCLog("TESTE SUCCESS");

                return JNI_VERSION_1_4;
        }
    }

从这一刻起,我们可以按如下方式调用Java方法:

void AddChild::callFlagMenu()
{
    jclass handlerClass = Controller::Instance()->env->FindClass("com/imobilemagic/mms/ui/AddChild/AddChild");
    if(handlerClass==NULL) {
        return;
    }
    jmethodID mid = Controller::Instance()->env->GetMethodID(handlerClass, "TestCall", "()V");
     if (mid == NULL) {
         return;
     }

     Controller::Instance()->env->CallVoidMethod(handlerClass, mid);

}

我希望我有所帮助! :)

0 个答案:

没有答案