JNI - вызывает метод Java автономно - PullRequest
0 голосов
/ 25 октября 2011

Ну, это мой первый вопрос по 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);

}

Chash приложения в "status = gJavaVM-> GetEnv((void **) & env, NULL); // CRASH HERE "

Кто-нибудь знает, как я могу так независимо запустить метод Java из C?Я хотел, чтобы C всегда вызывал метод Java.Единственный способ, которым я смог вызвать методы, - это вызвать метод C из java и через этот метод, как только мы получим параметр 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 для сохранения "env "типа JNIEnv.

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);

}

Я надеюсь, что помог!:)

...