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.

私の質問はこれです:どのjavascriptエンジンがウェブページ、埋め込まれたウェブビュー、またはアプリケーション内から使用されているかを判断する方法はありますか?

答えが「いいえ」の場合、Androidエミュレーターで使用されているJSエンジンを知っている人はいますか?


私がこれを求めている理由は、この問題のためです:http ://code.google.com/p/android/issues/detail?id=12987

基本的に、Android 2.3.XではJSCのjavascriptからjavaへのブリッジが壊れている可能性があり、これは私が作成しようとしているアプリケーションに影響を与えます。エミュレーターのJNIの奥深くからセグメンテーション違反が発生していますが、テストした少数の物理デバイスでは発生していません。これがエミュレーターのみのものなのか、JSCのみのものなのか、それともまったく別のものなのかを判断しようとしています。

4

3 に答える 3

19

より良い質問は、なぜ気にするのかということだと思います。あなたは基本的に、90年代後半から00年代前半に多くの人々が陥った「ブラウザ検出」の罠に陥っています。それ以来、特に、特定のブラウザでサポートされている機能が(ほとんど)移動するターゲットであったため、より便利なアプローチは機能検出であることがわかりました。現在、劇的に改善されたDOMとJavaScriptのサポートを備えたIE9で実行されているコードがあります。これは、ブラウザーの検出を実行し、IE6の手法にフォールバックしているため、これらの機能を使用していません。

したがって、V8とJSCについて心配するのではなく、必要な機能について心配するだけです。forEachJSCについては何も知りませんが、たとえば、V8(ECMAScript第5版標準の一部)にある配列のメソッドがないと仮定します。大きな「V8vs。JSC」レバーを投げるのではなく、次のようにします。

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

(「フォールバックするコード」がプロトタイプに追加 forEachされる場合があります。または、このテストが独自のイテレーター関数内にあり、ネイティブ実装に従うか、独自の実装を提供するかを知りたい場合があります。)

同様に、使用したい他の機能についても、存在する場合と存在しない場合があります。


しかし、本当にV8とJSCを検出する必要がある場合(そしてあなたのコメントからはそうかもしれません)、このページは非常に壊れやすいように見えますが、それを行う手段を示しているようです。これが私のわずかに編集されたバージョンです(特にwindow.devicePixelRatioテストに置き換えるためにWebkitAppearance —前者は少なくとも他のいくつかのブラウザで誤検知を出します[たとえば、FirefoxはWebKitではなくGeckoを使用します]):

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は、マングリングの影響を受けにくいシンボルの1つもリストされています。

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 に答える