如何检测运行时在 Android 中使用的 javascript 引擎(v8 或 JSC)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6768474/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I detect which javascript engine (v8 or JSC) is used at runtime in Android?
提问by digitalbath
Newer versions of Android ( > 2.2) include the v8 javascript engine, while older versions only had JSC. However, according to http://blogs.nitobi.com/joe/2011/01/14/android-your-js-engine-is-not-always-v8/, which javascript engine is used at runtime seems to depend on an environment variable present at build-time (JS_ENGINE
), as well as the hardware specs of the device:
较新版本的 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.
My question is this: is there any way that I can determine which javascript engine is in use from within a webpage, an embedded WebView, or an application?
我的问题是:有什么方法可以确定在网页、嵌入式 WebView 或应用程序中使用的是哪个 javascript 引擎?
If the answer is no, does anybody know which JS engine is used by the Android emulator?
如果答案是否定的,有谁知道 Android 模拟器使用的是哪个 JS 引擎?
The reason I'm asking this is because of this issue: http://code.google.com/p/android/issues/detail?id=12987
我问这个的原因是因为这个问题:http: //code.google.com/p/android/issues/detail?id=12987
Basically, it may be that the javascript-to-java bridge in JSC is broken on Android 2.3.X, and this impacts the application I'm trying to write. I'm seeing a segfault from somewhere deep in the JNI on my emulator, but not on the handful of physical devices I've tested. I'm trying to determine if this is an emulator-only thing, a JSC-only thing, or something different altogether.
基本上,可能是 JSC 中的 javascript-to-java 桥在 Android 2.3.X 上损坏了,这会影响我正在尝试编写的应用程序。我在模拟器上的 JNI 深处看到了段错误,但在我测试过的少数物理设备上却没有。我试图确定这是一个仅限模拟器的东西,仅限 JSC 的东西,还是完全不同的东西。
回答by T.J. Crowder
I think the better question is: Why do you care? You're basically falling into the "browser detection" trap that a lot of people fell into in the late 90's / early 00's. Since then, though, we've learned that it's feature detectionthat's the more useful approach, not least because the features supported in a given browser were (mostly) a moving target. There's code now, running on IE9 with its dramatically-improved DOM and JavaScript support, that's not using those features because it's doing browser detection and falling back on IE6 techniques.
我认为更好的问题是:你为什么关心?您基本上落入了许多人在 90 年代末 / 00 年代初落入的“浏览器检测”陷阱。不过,从那以后,我们了解到特征检测是更有用的方法,尤其是因为给定浏览器支持的特征(主要)是移动目标。现在有一些代码在 IE9 上运行,其显着改进的 DOM 和 JavaScript 支持没有使用这些功能,因为它正在执行浏览器检测并回退到 IE6 技术。
So rather than worrying about V8 vs. JSC, just worry about the features you want. I don't know anything about JSC, but for instance let's assume it doesn't have the forEach
method on arrays that V8 has (part of the ECMAScript 5th edition standard). Rather than throwing a big "V8 vs. JSC" lever, you'd do:
因此,与其担心 V8 与 JSC,不如担心您想要的功能。我对 JSC 一无所知,但例如让我们假设它没有forEach
V8 所拥有的数组方法(ECMAScript 第 5 版标准的一部分)。而不是抛出一个大的“V8 vs. JSC”杠杆,你会这样做:
if (typeof Array.prototype.forEach === "function") {
// Code that expects `forEach`
}
else {
// Code that falls back
}
(Your "code that falls back" might addforEach
to the prototype, or maybe this test is in your own iterator function and you want to know whether to defer to a native implementation or supply your own.)
(您的“回退代码”可能会添加forEach
到原型中,或者此测试可能在您自己的迭代器函数中,您想知道是遵循本机实现还是提供您自己的实现。)
And similarly for other features you want to use that may or may not be present.
同样,对于您想要使用的其他功能,可能存在也可能不存在。
But if you really need to detect V8 vs. JSC (and from your comment it seems you may), this pageseems to demonstrate a means of doing so, though it seems awfully fragile. Here's my slightly-edited version (not least to replace window.devicePixelRatio
with the test for WebkitAppearance
— the former gives false positives on at least some other browsers [Firefox, for instance, which uses Gecko, not WebKit]):
但是,如果您真的需要检测 V8 与 JSC(并且从您的评论看来您可以),这个页面似乎展示了一种这样做的方法,尽管它看起来非常脆弱。这是我稍微编辑过的版本(尤其是替换window.devicePixelRatio
为测试WebkitAppearance
- 前者至少在其他一些浏览器上给出误报 [例如,使用 Gecko 而不是 WebKit 的 Firefox]):
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");
}
Works for me detecting the difference between Chrome (which also uses V8) and Safari (which also uses JSC).
适用于我检测 Chrome(也使用 V8)和 Safari(也使用 JSC)之间的差异。
回答by soulseekah
Although the answer above points out the best methods, I thought I'd point out another way of doing this from inside a native library.
尽管上面的答案指出了最好的方法,但我想我会指出从本地库内部执行此操作的另一种方法。
void *dlWebCoreHandle = dlopen("libwebcore.so", RTLD_NOW);
void *v8GetVersion = dlsym(dlWebCoreHandle, "_ZN2v82V810GetVersionEv");
if (v8GetVersion == NULL) {
/* does not appear to be V8 */
} ... etc.
The exported symbols are mangled, unfortunately, so there is no 100% guarantee that the compiler used by your firmware manufacturer mangled the symbol in the same way (use nm --defined-only libwebcore.so -g
on a library with symbols). One would expose this function via the JNI and check from inside Java code.
不幸的是,导出的符号被破坏了,因此无法 100% 保证您的固件制造商使用的编译器以相同的方式破坏了符号(nm --defined-only libwebcore.so -g
在带有符号的库上使用)。可以通过 JNI 公开此函数并从 Java 代码内部进行检查。
The libwebcore.so
library also lists V8_Fatal
as one of the symbols, which is not susceptible to mangling.
该libwebcore.so
库还列出V8_Fatal
了不易被修改的符号之一。
JSC will have some other exported symbols that you can check for from inside a native library. If both are non-existent you can fallback to other methods.
JSC 将有一些其他导出的符号,您可以从本机库中检查这些符号。如果两者都不存在,您可以回退到其他方法。
回答by Erik Corry
var s = '';
for (x in {
3: 3,
1: 1
}) {
s += x
}
if (s === '31') {
alert('JSC');
} else {
alert('V8');
}
By the way this will categorize Firefox as 'JSC' and newer IE versions will look like V8.
顺便说一下,这会将 Firefox 归类为“JSC”,而较新的 IE 版本将类似于 V8。
My blog post has more V8 sniffing tricks: http://erikcorry.blogspot.dk/2012/12/which-version-of-v8-do-i-have.html
我的博文有更多 V8 嗅探技巧:http: //erikcorry.blogspot.dk/2012/12/which-version-of-v8-do-i-have.html