I have a huge problem when I want to change the Activity of my Android-Application with a JNI call from my C++ Code. The App uses cocos2d-x for rendering. The concrete situation is that I want to open the OpenFeint-Dashboard in Java using this very small function:
void launchOpenFeintDashboard() {
Dashboard.open();
}
This function is then called from C++ with a 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");
}
The JNIManager Class implementation is also very simple and 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;
}
From my point of view, cocos2d-x has some cirical problems when changing the activity with a JNI call, because I also get an App-Crash when changing the Activity to any own Activity.
BUT, also when I simply use OpenFeint to update an Achievement with a JNI call I get an App-Crash, similar as when changing the 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() + ")");
}
This brings me to a point on what I would say, that Android or Cocos2d-x has some problem when doing something asyncronously (update Achievement) or when changing the Activity in combination with using the NDK (I use NDKr7, but same on NDKr5).
You should also know that I already have some other functions defined in Java which are called with a JNI call and which work properly!
Maybe I've done something wrong, can somebody give me some advide on this or a working sample code of how to change the activity. Maybe it's a problem with Cocos2d-x.
Thanks.
Activity
? Have you checked this tutorial: blog.molioapp.com/2011/11/… – Casseycassi