2012-03-05 6 views
4

Итак, я разрабатываю небольшой проект с Cocos2Dx, но я пытаюсь добавить функциональность Bluetooth, и это подразумевает вызов нестатического метода, чтобы иметь возможность доступа к ассоциации основной деятельности с API Android , Почти все, что я видел, говорит мне следовать этой процедуре: - Создайте экземпляр основного действия (environment-> NewGlobalRef - это тот, который я использую) - Получить метод из действия и выполнить его (среда-> GetObjectClass)Как правильно позвонить от Android к нестатической функции в Java? (Cocos2Dx в миксе)

И вот код. В Java мы имеем следующее (опуская логический материал как OnCreate, onResume и т.д.):

public class TSP extends Cocos2dxActivity{ 
    public void CnxAttempt(){ 
     Log.e("TSP_BT","aTTEMPTING!"); 
    } 
} 

Вот оно! На данный момент я хочу показать сообщение журнала, подтверждающее, что функция выполнена. Теперь интересная часть находится на C++:

static JNIEnv* getJNIEnv(void){ 
    JNIEnv *env = 0; 

    // get jni environment 
    if (gJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK){ 
     CCLog("Failed to get the environment using GetEnv()"); 
    } 

    if (gJavaVM->AttachCurrentThread(&env, 0) < 0){ 
     CCLog("Failed to get the environment using AttachCurrentThread()"); 
    } 

    return env; 
} 
typedef struct JniMethodInfo_{ 
     JNIEnv * env;  // The environment 
     jclass  classID; // classID 
     jmethodID methodID; // methodID 
    } JniMethodInfo;   // Struct that stores most of the important information to relate to Java code 

    static bool getMethodInfo(JniMethodInfo &methodinfo, const char *methodName, const char *paramCode){ 
     jmethodID methodID = 0; 
     JNIEnv *pEnv = 0; 
     jobject methodObject = NULL; 

     bool bRet = false; 

     do { 
      pEnv = getJNIEnv(); 
      if (! pEnv){ 
       CCLog("getMethodInfo -- pEnv false"); 
       break; 
      } 

      jclass localRef = pEnv->FindClass("org/cocos2dx/tsp/TSP"); 
      if (localRef == NULL) { 
       CCLog("getMethodInfo -- localRefCls false"); 
       break; // exception thrown 
      } 

      gCallbackObject = pEnv->NewGlobalRef(localRef); 
      if (gCallbackObject == NULL){ 
       CCLog("getMethodInfo -- CallbackOBJ false"); 
       break; 
      } 

      jclass classID = pEnv->GetObjectClass(methodObject); 
      if (!classID){ 
       CCLog("getMethodInfo -- classID false"); 
       break; 
      } 

      methodID = pEnv->GetMethodID(classID, methodName, paramCode); 
      if (!methodID){ 
       CCLog("getMethodInfo -- methodID false"); 
       break; 
      } 
      methodinfo.classID = classID; 
      methodinfo.env = pEnv; 
      methodinfo.methodID = methodID; 
      CCLog("getMethodInfo -- methodinfo created"); 
      bRet = true; 
     } while(0); 

     return bRet; 
    } 

    void CnxAttempt(){ 
     JniMethodInfo methodInfo; // Creating a JniMethodInfo object to store all the data 

     if (! getMethodInfo(methodInfo, "CnxAttempt", "()V")){ 
      CCLog("getMethodInfo is FALSE :("); 
      return; 
     } 
     methodInfo.env->CallVoidMethod(methodObject,methodInfo.methodID); 
     methodInfo.env->DeleteLocalRef(methodInfo.classID); 
    } 

И все! При вызове CnxAttempt на C++ он переходит в BOOM, потому что он не распознает метод в классе Java и не может добраться до него ... Может кто-нибудь дать мне руку? Если что-то неясно, сообщите мне. Спасибо за кучу заранее!

ответ

3

Создание новой глобальной ссылки не Создайте новый объект. Разница между локальными и глобальными ссылками (из документов):

Локальные ссылки действительны во время вызова метода native и автоматически освобождаются после возвращения метода native. Глобальные ссылки остаются в силе до тех пор, пока они не будут явно освобождены.

Если вы хотите вызвать нестатический метод для объекта, вам необходимо передать объект на нативный метод (если он существует - не должен ли основной вид активности уже существовать?), Создайте новый с помощью функций NewObject * или путем вызова некоторого заводского метода.

Затем получите объект класса объекта, введите methodID и вызовите метод.

+0

Спасибо за ответ! Я фактически прекратил использовать функцию NewGlobalRef и начал использовать NewObject, но результаты там же. После нескольких исследований по этому вопросу и нескольких настроек в коде мне удалось перейти к нестатической функции, изменив порядок определений, следуя этому примеру: [link] (http://coding.derkeiler.com). /Archive/Java/comp.lang.java/2004-02/0570.html) Теперь мне приходится сталкиваться с тем, что любое использование внешних функций (таких как Bluetooth) из основного действия приведет к краху моего приложения, :( Но это для другого вопроса ... может быть. Спасибо большое! – ASM