如何在Android中检测运行时使用的javascript引擎(v8或JSC)?

dig*_*ath 12 javascript android v8 javascript-engine

较新版本的Android(> 2.2)包括v8 javascript引擎,而旧版本只有JSC.但是,根据http://blogs.nitobi.com/joe/2011/01/14/android-your-js-engine-is-not-always-v8/,运行时使用的javascript引擎似乎依赖于build-time(JS_ENGINE)中出现的环境变量,以及设备的硬件规格:

# The default / alternative engine depends on the device class.
# On devices with a lot of memory (e.g. Passion/Sholes), the
# default is V8. On everything else, the only choice is JSC.
Run Code Online (Sandbox Code Playgroud)

我的问题是:有什么方法可以确定在网页,嵌入式WebView或应用程序中使用哪个javascript引擎?

如果答案是否定的,那么有人知道Android模拟器使用了哪个JS引擎吗?


我问这个的原因是因为这个问题:http://code.google.com/p/android/issues/detail?id = 12987

基本上,可能是JSC中的javascript-to-java桥在Android 2.3.X上被破坏了,这会影响我正在尝试编写的应用程序.我在我的模拟器上看到了JNI深处的某个段错误,但是我测试过的少数几个物理设备上没有.我试图确定这是否只是一个模拟器,只有JSC的东西,或者完全不同的东西.

T.J*_*der 19

我认为更好的问题是:你为什么关心?您基本上陷入了"浏览器检测"陷阱,许多人在90年代末/ 00年代早期陷入困境.从那时起,我们已经了解到它的特征检测是更有用的方法,尤其是因为给定浏览器支持的功能(大多数)是移动目标.现在有代码,在IE9上运行,其显着改进的DOM和JavaScript支持,没有使用这些功能,因为它正在进行浏览器检测并回归IE6技术.

因此,不要担心V8与JSC,只需担心您想要的功能.我对JSC一无所知,但是例如我们假设它没有forEachV8所拥有的数组方法(ECMAScript第5版标准的一部分).你没有投入大的"V8 vs. JSC"杠杆,而是:

if (typeof Array.prototype.forEach === "function") {
    // Code that expects `forEach`
}
else {
    // Code that falls back
}
Run Code Online (Sandbox Code Playgroud)

(您的"后退代码"可能会添加 forEach到原型中,或者此测试可能位于您自己的迭代器函数中,您想知道是否遵循本机实现或提供自己的实现.)

同样地,您想要使用的其他功能可能存在也可能不存在.


但是如果你真的需要检测V8与JSC(并且你的评论似乎可能),这个页面似乎展示了这样做的方法,尽管它看起来非常脆弱.这是我的略微编辑的版本(至少替换window.devicePixelRatio为测试WebkitAppearance - 前者至少在其他一些浏览器上给出误报[例如,Firefox使用Gecko,而不是WebKit]):

var v8string = 'function%20javaEnabled%28%29%20%7B%20%5Bnative%20code%5D%20%7D';

if ('WebkitAppearance' in document.documentElement.style) { //If (probably) WebKit browser
    if (escape(navigator.javaEnabled.toString()) === v8string) {
        console.log('V8 detected');
    } else {
        console.log('JSC detected');
    }
} else {
    console.log("Not a WebKit browser");
}
Run Code Online (Sandbox Code Playgroud)

适合我检测Chrome(也使用V8)和Safari(也使用JSC)之间的区别.

  • 我关心的是这个问题:http://code.google.com/p/android/issues/detail?id = 12987 - 基本上,可能是JSC中的javascript-to-java桥在Android 2.3上被破坏了. X,这会影响我正在尝试编写的应用程序.我在我的模拟器上看到了JNI深处某个地方的段错误,我正在尝试确定这是一个仅限模拟器的东西,一个仅限JSC的东西,还是完全不同的东西. (9认同)
  • @digitalbath:啊。迷人的。(七个月了,谷歌基本上没有任何澄清。不好。)我已经更新了答案,指出了一些我希望有所帮助的内容。最好的, (2认同)

sou*_*kah 6

虽然上面的答案指出了最好的方法,但我想我会从本地库中指出另一种方法.

void *dlWebCoreHandle = dlopen("libwebcore.so", RTLD_NOW);
void *v8GetVersion = dlsym(dlWebCoreHandle, "_ZN2v82V810GetVersionEv");
if (v8GetVersion == NULL) {
    /* does not appear to be V8 */
} ... etc.
Run Code Online (Sandbox Code Playgroud)

遗憾的是,导出的符号被破坏,因此没有100%保证固件制造商使用的编译器以相同的方式损坏符号(nm --defined-only libwebcore.so -g在带符号的库上使用).一个人会通过JNI公开这个函数,并从Java代码中检查.

libwebcore.so库还列出V8_Fatal了一个符号,它不易受到损坏.

JSC将有一些其他导出的符号,您可以从本机库中检查.如果两者都不存在,您可以回退到其他方法.