У меня огромная проблема, когда я хочу изменить активность моего 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 также очень проста и проста:
#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, потому что я также получаю App-Crash при изменении действия на любое собственное действие.
НО, также, когда я просто использую OpenFeint для обновления Достижения с помощью вызова JNI, я получаю App-Crash, аналогично тому, как при изменении Activity:
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.
Спасибо.