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

问题描述 投票:0回答:3

较新版本的 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 引擎?

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


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

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

javascript android v8 javascript-engine
3个回答
19
投票

我认为没有可靠的方法可以做到这一点。我在下面提供了一种黑客攻击(截至 2024 年 3 月的编辑,该黑客攻击仍然有效),但随着时间的推移,类似的黑客攻击往往会停止工作(正如另一个答案中的黑客所做的那样)。

但是一个框架挑战:你为什么关心?你基本上陷入了“浏览器检测”陷阱,很多人在 90 年代末/00 年代初都陷入了这种陷阱。但从那时起,我们了解到“功能检测”是更有用的方法,尤其是因为给定浏览器支持的功能(大部分)是移动目标。现在有代码在 IE9 上运行,其 DOM 和 JavaScript 支持得到了显着改进,但没有使用这些功能,因为它正在执行浏览器检测并依赖 IE6 技术。 因此,不用担心 V8 与 JSC,只需担心您想要的功能即可。我对 JSC 一无所知,但例如,我们假设它没有 V8 所具有的数组上的

forEach

方法(ECMAScript 第 5 版标准的一部分)。与其抛出一个“V8 vs. JSC”的大杠杆,你应该这样做:

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

(您的“回退代码”可能会 
add

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)之间的差异。

目前还不清楚为什么该代码使用

escape

并与转义字符串进行比较;区别似乎只是所使用的空白类型(JSC 为换行符,V8 为空格)。我还让这一点对“

javaEnabled
”在未来某个时候甚至可能不存在的想法变得友好:

var v8string = "function javaEnabled() { [native code] }"; if ("WebkitAppearance" in document.documentElement.style) { // If (probably) WebKit browser if (String(navigator.javaEnabled) === v8string) { console.log("V8 detected"); } else { console.log("JSC detected"); } } else { console.log("Not a WebKit browser"); }


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 将有一些其他导出的符号,您可以从本机库中检查它们。如果两者都不存在,您可以回退到其他方法。


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

© www.soinside.com 2019 - 2024. All rights reserved.