当我想通过 C++ 代码中的 JNI 调用更改我的 Android 应用程序的 Activity 时,我遇到了一个大问题。App 使用 cocos2d-x 进行渲染。具体情况是我想用这个很小的函数在Java中打开OpenFeint-Dashboard:
void launchOpenFeintDashboard() {
Dashboard.open();
}
然后使用简单的 JNI-Call 从 C++ 调用此函数:
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 调用更改 Activity 时存在一些问题,因为在将 Activity 更改为任何自己的 Activity 时,我也会遇到 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 在异步执行某些操作(更新成就)或更改 Activity 并结合使用 NDK(我使用 NDKr7,但在 NDKr5 上相同)时会出现一些问题.
您还应该知道,我已经在 Java 中定义了一些其他函数,这些函数通过 JNI 调用调用并且可以正常工作!
也许我做错了什么,有人可以给我一些建议或如何更改活动的工作示例代码。可能是 Cocos2d-x 的问题。
谢谢。