Изменение действия с вызовом JNI или использование Openfeint вызывает сбой приложения.

У меня возникает огромная проблема, когда я хочу изменить действие своего Android-приложения с помощью вызова JNI из моего кода C++. Приложение использует cocos2d-x для рендеринга. Конкретная ситуация такова, что я хочу открыть OpenFeint-Dashboard в Java, используя эту очень маленькую функцию:

void launchOpenFeintDashboard() {
    Dashboard.open();
}

Затем эта функция вызывается из C++ с помощью простого вызова JNI:

void
OFWrapper::launchDashboard() {
// init openfeint
CCLog("CPP Init OpenFeint Dashboard");

CCDirector::sharedDirector()->pause();

jmethodID javamethod = JNIManager::env()->GetMethodID(JNIManager::mainActivity(), "launchOpenFeintDashboard", "()V");
if (javamethod == 0)
    return;
JNIManager::env()->CallVoidMethod( JNIManager::mainActivityObj(), javamethod );

CCLog("CPP Init OpenFeint Dashboard done");
}

Реализация класса JNIManager также очень проста и basic:

#include "JNIManager.h"
#include <cstdlib>

static JNIEnv* sJavaEnvironment = NULL;
static jobject sMainActivityObject = NULL;
static jclass  sMainActivity = NULL;


extern "C" {
    JNIEXPORT void JNICALL Java_net_plazz_mainzelapp_mainzelapp_sendJavaEnvironment(JNIEnv* env, jobject obj);
};

// this function is called from JAVA at startup to get the env
JNIEXPORT void JNICALL Java_net_plazz_mainzelapp_mainzelapp_sendJavaEnvironment(JNIEnv* env, jobject obj)
{
sJavaEnvironment = env;
sMainActivityObject = obj;
sMainActivity = JNIManager::env()->GetObjectClass(obj);
}



JNIEnv* 
JNIManager::env() 
{
return sJavaEnvironment;
}

jobject 
JNIManager::mainActivityObj() 
{
return sMainActivityObject;
}

jclass 
JNIManager::mainActivity() 
{
return sMainActivity;
}

С моей точки зрения, у cocos2d-x есть некоторые проблемы при изменении действия с помощью вызова JNI, потому что я также получаю сбой приложения при изменении действия на любое собственное действие.

НО, также, когда я просто использую OpenFeint для обновления достижения с помощью вызова JNI, я получаю App-Crash, подобный тому, как при изменении действия:

void updateAchievementProgress( final String achievementIdStr, final String progressStr ) {
    Log.v("CALLBACK", "updateAchievementProgress (tid:" + Thread.currentThread().getId() + ")");

    float x = Float.valueOf(progressStr).floatValue();
    final Achievement a = new Achievement(achievementIdStr);
    a.updateProgression(x, new Achievement.UpdateProgressionCB() {
        @Override
        public void onSuccess(boolean b) {
            Log.e("In Achievement", "UpdateProgression");
            a.notifyAll();
        }

        @Override
        public void onFailure(String exceptionMessage) {
            Log.e("In Achievement", "Unlock failed");
            a.notifyAll();
        }
    });
    Log.v("CALLBACK", "updateAchievementProgress done (tid:" + Thread.currentThread().getId() + ")");
}

Это подводит меня к тому, что я бы сказал, что Android или Cocos2d-x имеет некоторые проблемы при выполнении чего-либо асинхронно (обновление достижения) или при изменении действия в сочетании с использованием NDK (я использую NDKr7, но то же самое на NDKr5).

Вы также должны знать, что у меня уже есть некоторые другие функции, определенные в Java, которые вызываются вызовом JNI и работают правильно!

Может быть, я сделал что-то не так, может кто-нибудь дать мне совет по этому поводу или рабочий пример кода, как изменить активность. Возможно, это проблема с Cocos2d-x.

Спасибо.

5
задан Andy Reimann 8 March 2012 в 10:50
поделиться