使用V8 JavaScript引擎在没有Web视图的情况下执行JS lib

时间:2013-10-16 16:02:23

标签: javascript webview v8

我正在开发一个JavaScript组件,负责向服务器发出请求并将结果分派给UI。通过在JavaScript中执行此操作,我可以在多种类型的UI中使用我的组件:Android应用程序,iOS应用程序,桌面应用程序(QT),Web应用程序......

所有这些UI都实例化了一个Web视图,因此当UI加载专用URL(webview.load("file://myfirstWebPage.html"))时,我的组件就会启动。

第一个网页加载所有JavaScript组件,完成后,UI可以向JavaScript组件发出一些请求,这会向服务器发出请求,当它有响应时,它会将其发送回客户端(UI Android,UI iOS ...)

这种架构运行良好,但我想知道是否有其他方法可以在不使用每个客户端的Web视图的情况下加载JavaScript组件?

V8引擎可以帮助我吗?

4 个答案:

答案 0 :(得分:17)

如果我理解您的问题,那么您正在寻找一种在不使用WebView的情况下跨多个平台(iOS,Android等)执行JavaScript的方法。该解决方案将是特定于平台的,因为即使底层WebView实现对于每个平台也是不同的。

对于Android,只要设备附带V8,您就可以create a new V8 Context via its API并使用它来执行JavaScript。该设备实际上必须随V8一起提供。 This answer可能会对您有所帮助。

对于使用JavaScriptCore的iOS,iOS7中的最新发展已经允许您加载和运行任意JavaScript代码。 Read more here

答案 1 :(得分:6)

我不知道如何使用V8,但您可以使用Rhino库。也没有涉及WebView。

Download Rhino首先解压缩,将js.jar文件放在libs文件夹下。它非常小,所以你不必担心你的apk文件会因为这个外部jar而变得非常大。

以下是一些执行JavaScript代码的简单代码。

Object[] params = new Object[] { "javaScriptParam" };

// Every Rhino VM begins with the enter()
// This Context is not Android's Context
Context rhino = Context.enter();

// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
try {
    Scriptable scope = rhino.initStandardObjects();

    // Note the forth argument is 1, which means the JavaScript source has
    // been compressed to only one line using something like YUI
    rhino.evaluateString(scope, javaScriptCode, "JavaScript", 1, null);

    // Get the functionName defined in JavaScriptCode
    Object obj = scope.get(functionNameInJavaScriptCode, scope);

    if (obj instanceof Function) {
        Function jsFunction = (Function) obj;

        // Call the function with params
        Object jsResult = jsFunction.call(rhino, scope, scope, params);
        // Parse the jsResult object to a String
        String result = Context.toString(jsResult);
    }
} finally {
    Context.exit();
}

您可以在my post看到更多详情。

答案 2 :(得分:6)

对于Android部分。我使用了J2V8 JavaScript库。它是Google V8 JavaScript引擎的Java包装器。有关详细信息,请参阅here

答案 3 :(得分:1)

我发现这个非常漂亮的开源ECMAScript兼容的JS引擎完全用C编写,名为duktape

  

Duktape是一个可嵌入的Javascript引擎,专注于可移植性和紧凑的占用空间。

你仍然需要经历ndk-jni业务,但它非常直接。只需将可分发来源here中的duktape.cduktape.h(如果您不想自己完成构建过程)包含到jni文件夹中,请更新Android.mk和所有内容那东西。

这是一个示例C片段,可以帮助您入门。

#include "duktape.h"

JNIEXPORT jstring JNICALL
Java_com_ndktest_MainActivity_evalJS
(JNIEnv * env, jobject obj, jstring input){
    duk_context *ctx = duk_create_heap_default();
    const char *nativeString = (*env)->GetStringUTFChars(env, input, 0);
    duk_push_string(ctx, nativeString);
    duk_eval(ctx);
    (*env)->ReleaseStringUTFChars(env, input, nativeString);
    jstring result = (*env)->NewStringUTF(env, duk_to_string(ctx, -1));
    duk_destroy_heap(ctx);
    return result;
}
祝你好运!