13

较新版本的 Android (> 2.2) 包括 v8 javascript 引擎,而旧版本只有 JSC。但是,根据http://blogs.nitobi.com/joe/2011/01/14/android-your-js-engine-is-not-always-v8/,在运行时使用哪个 javascript 引擎似乎取决于构建时存在的环境变量 ( 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.

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

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


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

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

4

3 回答 3

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
}

(您的“回退代码”可能会添加 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");
}

对我有用,检测 Chrome(也使用 V8)和 Safari(也使用 JSC)之间的区别。

于 2011-07-20T21:09:14.370 回答
6

尽管上面的答案指出了最好的方法,但我想我会从本机库中指出另一种方法。

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

不幸的是,导出的符号被破坏了,因此不能 100% 保证固件制造商使用的编译器以相同的方式破坏符号(nm --defined-only libwebcore.so -g在带有符号的库上使用)。可以通过 JNI 公开这个函数并从 Java 代码内部进行检查。

libwebcore.so库还将V8_Fatal符号之一列为不易损坏的符号。

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

于 2012-08-06T11:46:11.767 回答
2

var s = '';
for (x in {
    3: 3,
    1: 1
  }) {
  s += x
}
if (s === '31') {
  alert('JSC');
} else {
  alert('V8');
}

顺便说一下,这会将 Firefox 归类为“JSC”,较新的 IE 版本看起来像 V8。

我的博文有更多 V8 嗅探技巧:http ://erikcorry.blogspot.dk/2012/12/which-version-of-v8-do-i-have.html

于 2012-12-07T09:36:22.637 回答