Tengo un gran problema cuando quiero cambiar la actividad de mi Android-aplicación con una llamada JNI de mi código C++. La aplicación usa cocos2d-x para renderizar. La situación concreta es que quiero abrir el OpenFeint-tablero de instrumentos en Java utilizando esta pequeña función:cambia su actividad con JNI llamadas o usando Openfeint causa de App-Crash
void launchOpenFeintDashboard() {
Dashboard.open();
}
Esta función se llama luego desde C++ con un simple JNI-Call:
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");
}
la aplicación JNIManager clase es también muy simple y básica:
#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;
}
Desde mi punto de vista, cocos2d-x tiene algunos problemas cuando se cambia el cirical actividad con una llamada JNI, porque también obtengo un bloqueo de aplicación al cambiar la actividad a cualquier actividad propia.
PERO, también cuando simplemente uso OpenFeint para actualizar un logro con una JNI llaman consigo una App-colisión, similar a cuando se cambia la Actividad:
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() + ")");
}
Esto me lleva a un punto en lo que Diría que Android o Cocos2d-x tienen algún problema al hacer algo asincrónicamente (actualizar Logro) o al cambiar la Actividad en combinación con el uso del NDK (yo uso NDKr7, pero igual en NDKr5).
También debe saber que ya tengo algunas otras funciones definidas en Java que se denominan con una llamada JNI, y que funcione correctamente!
Tal vez he hecho algo mal, ¿alguien me puede dar alguna información sobre este o un código de muestra de trabajo sobre cómo cambiar la actividad? Tal vez es un problema con Cocos2d-x.
Gracias.
AFAIK el env JNI solo es válido mientras la llamada de función esté activa ... Tampoco se puede garantizar que el objeto siga siendo válido. Básicamente, necesitamos ver cómo terminas en la llamada al launchDashboard. es decir, desde la entrada inicial al nativo de java ... – Goz
¿Por qué tienes más de una 'Actividad'? ¿Has revisado este tutorial ?: http://blog.molioapp.com/2011/11/openfeint-and-admob-integrated-with.html – Macarse