1.2.2beta2的安卓版evalString可用么

我把ScriptingCore的cpp和h文件修改了,然后重新发布打包,安卓的启动后直接:
10-28 01:58:35.805: A/libc(14886): Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 14903 (Thread-6318)

1.3的时间来不及了。今天必须把所有bug解决掉了。后续再用1.3来弄。

启动后是调用了 evalString 吗?

嗯,放在helper类的方法里:
public static void onEnterForeground() {

    if (sCocosSound != null) {
        sCocosSound.onEnterForeground();
    }

    if (sCocosMusic != null) {
        sCocosMusic.onEnterForeground();
    }
    Cocos2dxJavascriptJavaBridge.evalString("console.log('######java onEnterForeground#######');");   
	//Cocos2dxJavascriptJavaBridge.evalString("cc.find('Game').getComponent('Player').onBeforeWillEnterForeground();");
}

Android 调试很困难,能不能用 Visual Studio 或者 Xcode 跟踪一下崩溃调用栈?

一般建议等 Mac / Win 版本跑通没问题了再做 Android

1赞

我用Xcode试试,creator构建,编译时候没通过:

Undefined symbols for architecture i386:
“ScriptingCore::evalString(char const*, JS::MutableHandleJS::Value)”, referenced from:
-[AppController applicationWillResignActive:] in AppController.o
-[AppController applicationDidBecomeActive:] in AppController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

这是在 iOS 平台找不到 ScriptingCore::evalString(char const*, JS::MutableHandle) 的实现,你检查一下 cpp 文件中的匹配,有可能是 const char * 改为 std::string 了

cpp中的实现也是从1.3中直接复制的呀,我看了是const char *

/*
bool ScriptingCore::evalString(const char *string, jsval outVal, const char filename, JSContext cx, JSObject global)
{
if (cx == NULL)
cx = _cx;
if (global == NULL)
global = _global.ref().get();

JSAutoCompartment ac(cx, global);
JS::RootedObject jsglobal(cx, global);
return JS_EvaluateScript(cx, jsglobal, string, (unsigned)strlen(string), "ScriptingCore::evalString", 1);

}
*/
//changed
bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal, const char filename, JSContext cx, JS::HandleObject global)
{
JSAutoCompartment ac(cx, global);
JS::PersistentRootedScript script(cx);

JS::CompileOptions op(cx);
op.setUTF8(true);

std::string content = string;

bool ok = false;
bool evaluatedOK = false;
if (!content.empty())
{
    ok = JS::Compile(cx, global, op, content.c_str(), content.size(), &(script) );
}
if (ok) {
    evaluatedOK = JS_ExecuteScript(cx, global, script, outVal);
    if (false == evaluatedOK) {
        cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", content.c_str());
        JS_ReportPendingException(cx);
    }
}
else {
    cocos2d::log("ScriptingCore:: evaluateScript fail: %s", content.c_str());
}
return evaluatedOK;

}

bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal)
{
JS::RootedObject global(_cx, _global->get());
return evalString(string, outVal, nullptr, _cx, global);
}

bool ScriptingCore::evalString(const char *string)
{
JS::RootedValue retVal(_cx);
return evalString(string, &retVal);
}
//changed end

我用的binary方式,我修改了下发布路径,就可以在creator上编译通过了,bianry方式编译不会自动更换原路径下的so库么?

在xcode下编译安装报错:

Undefined symbols for architecture arm64:
“ScriptingCore::evalString(char const*, JS::MutableHandleJS::Value)”, referenced from:
-[AppController applicationWillResignActive:] in AppController.o
-[AppController applicationDidBecomeActive:] in AppController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

呃,我仔细看了一下,你是在一启动就调用了 evalString,这样是有问题的,这个时候 JS 环境都还没准备好,在 AppDelegate::applicationDidFinishLaunching 里面才会初始化 JS 引擎。

Undefined Symbols 问题我不是很理解,按理说如果找不到应该是编译阶段就报错了,链接阶段报错说明头文件引用没问题,已经找到函数定义,但是函数实现找不到,一般情况下都是因为函数的参数或者返回值类型在声明和定义不同导致的,不过我没在你贴出来的代码里找到问题

Binary 如果可以编译通过说明还是你引用的引擎有可能有问题,你是用的 Creator 标准内置引擎完全没有改动吗?

ios在1.2和1.3里,这个位置调用没有问题的,可以成功调用,并且通过逻辑解决了暂停切出切入的bug。安卓1.3也可以成功调用。

另:引擎从来没改过。只是这次修改了scriptingcore的h和cpp

现在用未改动的1.2,ios可以evalstring,只是没有返回值,安卓直接退出。

官方可以打个1.2.2beta的补丁包么,只增加安卓的evalstring功能的。安卓的evalstring在以前的低版本中也是可以的吧

你是用干净的环境,build 出原生版本,然后在原生版本的 iOS_mac 工程里面修改这些内容,然后重新编译的对吧?

你把你的 ScriptingCore.h / .cpp 以及调用了 evalString 的文件一起发给我看看吧

我用的binary方式,我到creator的安装目录下,找到cpp和h文件,修改的。
source.zip (26.3 KB)

怪不得,binary 摸版中的 cocos 引擎是预编译好的,所以你改 creator 目录下的 cpp 没有用。你需要用 link 或者 default 摸版

附件是default方式,creator编译未通过的错误:
native.log.zip (6.0 KB)

这就比较对了,这是 1.2 到 1.3 的接口改变导致的

需要把 _global->get() 改成 _global.ref().get()

还有,你既然在调试阶段,就不要用 Creator 来进行编译了,出了错不方便看,直接用 Xcode 编译会效率高很多

1赞

ios的按照这个修改后,可以得到返回值啦。

安卓的编译报错:
Building mode: debug
Using Eclipse project : /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android
running: ‘/Users/allen/Documents/adt-bundle-mac-x86_64-20140702/sdk/tools/android update project -t android-14 -p /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android’

Updated project.properties
Updated local.properties
Updated file /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android/proguard-project.txt
It seems that there are sub-projects. If you want to update them
please use the --subprojects parameter.
running: ‘/Users/allen/Documents/adt-bundle-mac-x86_64-20140702/sdk/tools/android update lib-project -p /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/platform/android/java -t android-10’

Updated project.properties
Updated local.properties
Updated file /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/platform/android/java/proguard-project.txt
Building native…
NDK build mode: debug
NDK_TOOLCHAIN_VERSION: 4.9
running: ‘/Users/allen/Documents/CocosProjects/android/android-ndk-r10e/ndk-build -C /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android -j4 NDK_MODULE_PATH=/Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x:/Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos:/Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external NDK_TOOLCHAIN_VERSION=4.9 NDK_DEBUG=1’

Android NDK: WARNING: APP_PLATFORM android-14 is larger than android:minSdkVersion 9 in ./AndroidManifest.xml
make: Entering directory /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android' [armeabi-v7a] Compile++ arm : cocos2d_js_static <= CCJavascriptJavaBridge.cpp [armeabi-v7a] StaticLibrary : libcocos2d.a [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCComController.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCComRender.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCInputDelegate.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= DictionaryHelper.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CocoLoader.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCFrame.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCTimeLine.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCActionTimeline.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCActionTimelineNode.cpp [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCBoneNode.cpp In file included from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/js/CallArgs.h:38:0, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/jsapi.h:26, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/manual/platform/android/CCJavascriptJavaBridge.h:29, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/proj.android/../manual/platform/android/CCJavascriptJavaBridge.cpp:24: /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h: In function 'jint Java_org_cocos2dx_lib_Cocos2dxJavascriptJavaBridge_evalString(JNIEnv*, jclass, jstring)': /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h:520:5: error: 'JS::MutableHandle<T>::MutableHandle(N, typename mozilla::EnableIf<((mozilla::IsNullPointer<N>::value || mozilla::IsSame<N, int>::value) || mozilla::IsSame<N, long int>::value), int>::Type) [with N = std::nullptr_t; T = JS::Value; typename mozilla::EnableIf<((mozilla::IsNullPointer<N>::value || mozilla::IsSame<N, int>::value) || mozilla::IsSame<N, long int>::value), int>::Type = int]' is private MutableHandle(N, ^ /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/proj.android/../manual/platform/android/CCJavascriptJavaBridge.cpp:49:71: error: within this context ScriptingCore::getInstance()->evalString(strValue.c_str(), nullptr); ^ /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/proj.android/../manual/platform/android/CCJavascriptJavaBridge.cpp:49:71: error: use of deleted function 'JS::MutableHandle<T>::MutableHandle(N, typename mozilla::EnableIf<((mozilla::IsNullPointer<N>::value || mozilla::IsSame<N, int>::value) || mozilla::IsSame<N, long int>::value), int>::Type) [with N = std::nullptr_t; T = JS::Value; typename mozilla::EnableIf<((mozilla::IsNullPointer<N>::value || mozilla::IsSame<N, int>::value) || mozilla::IsSame<N, long int>::value), int>::Type = int]' In file included from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/js/CallArgs.h:38:0, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/jsapi.h:26, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/manual/platform/android/CCJavascriptJavaBridge.h:29, from /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/cocos/scripting/js-bindings/proj.android/../manual/platform/android/CCJavascriptJavaBridge.cpp:24: /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/cocos2d-x/external/android/armeabi-v7a/include/spidermonkey/js/RootingAPI.h:520:5: note: declared here MutableHandle(N, ^ [armeabi-v7a] Compile++ thumb: cocostudio_static <= CCSkeletonNode.cpp make: *** [obj/local/armeabi-v7a/objs-debug/cocos2d_js_static/__/manual/platform/android/CCJavascriptJavaBridge.o] Error 1 make: *** Waiting for unfinished jobs.... make: Leaving directory /Users/allen/Documents/CocosProjects/mql-build/jsb-default/frameworks/runtime-src/proj.android’
Error running command, return code: 2.

https://github.com/cocos-creator/cocos2d-x-lite/blob/v1.2/cocos/scripting/js-bindings/manual/platform/android/CCJavascriptJavaBridge.cpp#L49

这一行把 evalString 的第二个参数去掉

1赞

按照这个修改,可以编译通过了:
Cocos2dxJavascriptJavaBridge.evalString(“console.log(’######java onEnterForeground#######’);”);
把这个语句放在activity的onpause里可以执行。

但是放在helper的onEnterForeground方法里就直接fatal 闪退了,在1.3里为什么放在这个位置就可以执行呢?需要怎么改才有可能可以在这调用呢?

这应该是因为第一次进入的时候 JS 环境还没有准备好,你可以在 onEnterForeground 中检查一下

ScriptingCore::getInstance()->getGlobalContext()

如果 context 已经存在就可以调用,否则不可以调用

我在onEnterBackground设置了一个参数,可以判断了,然后调用成功了,非常感谢panda大神耐心细致的解答和帮助:)
解决了游戏内手动暂停后,切出切入的暂停问题。感谢panda和cocos团队。

另:1.3的不用判断是否js环境已经准备好了。