Как я могу определить, какой движок JavaScript (v8 или JSC) используется во время выполнения в Android?
Более новые версии Android ( > 2.2) включают движок JavaScript v8, в то время как в более старых версиях был только 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.
У меня такой вопрос: могу ли я определить, какой движок JavaScript используется на веб-странице, во встроенном WebView или в приложении?
Если ответ "нет", кто-нибудь знает, какой движок JS используется эмулятором Android?
Я спрашиваю об этом из-за этой проблемы: http://code.google.com/p/android/issues/detail?id=12987
По сути, это может быть связано с тем, что на Android 2.3.X не работает мост javascript-to-java в JSC, и это влияет на приложение, которое я пытаюсь написать. Я вижу segfault где-то глубоко в JNI на моем эмуляторе, но не на нескольких физических устройствах, которые я тестировал. Я пытаюсь определить, является ли это вещью только для эмулятора, только для АО или чем-то другим.
3 ответа
Я думаю, что лучший вопрос: почему тебя это волнует? Вы попадаете в ловушку "обнаружения браузеров", в которую многие попали в конце 90-х - начале 00-х годов. С тех пор, однако, мы узнали, что именно обнаружение функций является более полезным подходом, не в последнюю очередь потому, что функции, поддерживаемые в данном браузере, были (в основном) движущейся целью. Теперь есть код, работающий на IE9 с его существенно улучшенной поддержкой DOM и JavaScript, который не использует эти функции, потому что он выполняет обнаружение браузера и использует методы IE6.
Так что вместо того, чтобы беспокоиться о V8 vs. JSC, просто беспокойтесь о функциях, которые вы хотите. Я ничего не знаю об АО, но давайте предположим, что у него нет forEach
метод для массивов, который есть в V8 (часть стандарта 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).
Хотя ответ выше указывает на лучшие методы, я думал, что укажу другой способ сделать это из нативной библиотеки.
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 будут некоторые другие экспортируемые символы, которые вы можете проверить изнутри собственной библиотеки. Если оба не существуют, вы можете использовать другие методы.
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