【问题标题】:Use V8 JavaScript engine to execute JS lib without web view使用 V8 JavaScript 引擎在没有 web 视图的情况下执行 JS lib
【发布时间】:2013-10-24 20:27:37
【问题描述】:

我正在开发一个 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 引擎能帮到我吗?

【问题讨论】:

标签: javascript webview v8


【解决方案1】:

如果我理解您的问题,那么您正在寻找一种在不使用 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.

【讨论】:

  • 非常有趣的答案。我会探索你的建议
【解决方案2】:

对于 Android 部分。我使用了J2V8 JavaScript 库。它是 Google 的 V8 JavaScript 引擎的 Java 包装器。详情请见here

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @Sender 我只用必要的链接编辑了答案。我认为现在可以(?)。
【解决方案3】:

我不知道如何使用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查看更多详细信息。

【讨论】:

  • 要在 android(跨平台)上工作,您需要调用 Context.setOptimizationLevel(-1); 其中 Context 是 Rhino 的 Context 类的一个实例。
【解决方案4】:

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

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

您仍然需要通过 ndk-jni 业务,但这很简单。只需将可分发源 here(如果您不想自己完成构建过程)中的 duktape.cduktape.h 包含到 jni 文件夹中,更新 Android.mk 和所有这些东西。

这里有一个示例 C sn-p 可以帮助您入门。

#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;
}

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 2020-04-06
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 2014-05-11
    • 2018-08-13
    • 2010-11-20
    相关资源
    最近更新 更多