Hi,
I’ve run into a crash that I don’t really understand, and am hoping for help sorting out. I suspect that this may be some form of threading problem, but I’m not sure. Any help or angles of investigation will be appreciated!
The setup:
I’m trying to complete facebook login. I’ve got it working correctly in Java, but when I try to pass the string back up to JS I get a crash with the below stack:
#00 pc 001ca13a /data/data/com.redhotlabs.bingo/lib/libgame.so (JS::InNoGCScope()+17)
#01 pc 002ef919 /data/data/com.redhotlabs.bingo/lib/libgame.so
#02 pc 001d27af /data/data/com.redhotlabs.bingo/lib/libgame.so (JS_NewStringCopyZ+62)
#03 pc 00151449 /data/data/com.redhotlabs.bingo/lib/libgame.so (JSStringCallback::callbackFunc(char const*)+64)
#04 pc 00142fb7 /data/data/com.redhotlabs.bingo/lib/libgame.so (Java_com_redhotlabs_bingo_FacebookManager_currentFacebookUserChanged+46)
#05 pc 0001f3b0 /system/lib/libdvm.so (dvmPlatformInvoke+112)
#06 pc 0004eb6f /system/lib/libdvm.so (dvmCallJNIMethod(unsigned int const*, JValue*, Method const*, Thread*)+394)
#07 pc 00050c8b /system/lib/libdvm.so (dvmResolveNativeMethod(unsigned int const*, JValue*, Method const*, Thread*)+174)
#08 pc 000288a4 /system/lib/libdvm.so
the Java code (all of this seems to work fine, and the json encoded string being passed to c*+ is correct:
<pre>
public native void currentFacebookUserChanged;
/* Displays the facebook login dialog./
public void showLoginDialog {
// start Facebook Login
Session.openActiveSession;
}
private class SessionStatusCallback implements Session.StatusCallback {
Override public void call(Session session, SessionState state, Exception exception) { if (session.isOpened()) { // make request to the /me API Request.executeMeRequestAsync(session, new Request.GraphUserCallback() { // callback after Graph API response with user object
Override
public void onCompleted {
if {
String data = user.getInnerJSONObject.toString;
FacebookManager.getInstance.currentFacebookUserChanged;
}
}
}
}
}
}
</pre>
my c*+ code:
//JSStringCallback extends JSCallbackWrapper, and is retained when passed down to the c++ code
static JSStringCallback* s_userChangedListener;
extern "C"
{
void Java__FacebookManager_currentFacebookUserChanged(JNIEnv* env, jobject thiz, jstring data) {
if(s_userChangedListener) {
const char* nativeData = (env)->GetStringUTFChars( data, 0);
s_userChangedListener->callbackFunc(nativeData);
}
}
}
the JSStringCallback’s callFunc code:
void JSStringCallback::callbackFunc(const char* arg) {
JSObject* thisObj = JSVAL_IS_VOID(jsThisObj) ? NULL : JSVAL_TO_OBJECT(jsThisObj);
JSContext *cx = ScriptingCore::getInstance()->getGlobalContext();
jsval retval;
if(jsCallback != JSVAL_VOID) {
CCLog(arg); //This properly prints out the json string of the FB user data
JSString *str = JS_NewStringCopyZ(cx, arg); //This line throws the error
jsval senderVal = STRING_TO_JSVAL(str);
JS_AddValueRoot(cx, &senderVal);
JS_CallFunctionValue(cx, thisObj, jsCallback, 1, &senderVal, &retval);
JS_RemoveValueRoot(cx, &senderVal);
// JS_CallFunctionValue(cx, thisObj, jsCallback, 0, NULL, &retval); //This line will also throw the error if the above lines are commented out
}
}
I’ve tried putting the c++ call into the UI thread in java using an Async task, but that doesn’t seem to have changed anything.
Thanks for any help you can give,
Mark Henderson