使用 V8 JavaScript 引擎在没有 web view 的情况下执行 JS lib

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19408245/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 15:29:49  来源:igfitidea点击:

Use V8 JavaScript engine to execute JS lib without web view

javascriptwebviewv8

提问by wawanopoulos

I am developing a JavaScript component which is responsible for making requests to the server and dispatching results to the UI. By doing this in JavaScript, I am able to use my component in several types of UI: Android app, iOS app, desktop app (QT), web app...

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

All these UI have instantiated a web view, so my component is started when the UI loads the dedicated URL (webview.load("file://myfirstWebPage.html")).

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

This first web page loads all the JavaScript components, and when it's done, the UI is able to make some requests to the JavaScript component, which makes a request to the server and when it has the response, it dispatches it back to the client (UI Android, UI iOS ...)

第一个网页加载了所有的 JavaScript 组件,当它完成时,UI 能够向 JavaScript 组件发出一些请求,它向服务器发出请求,当它有响应时,它将它分派回客户端(用户界面 Android,用户界面 iOS ...)

This architecture works fine, but I would like to know if there is another way to load the JavaScript component without using a web view on each client?

这种架构工作正常,但我想知道是否有另一种方法可以在不使用每个客户端上的 web 视图的情况下加载 JavaScript 组件?

Can the V8 engine help me?

V8 引擎可以帮助我吗?

回答by Andrew

If I'm understanding your question, you're looking for a way to execute JavaScript across many platforms (iOS, Android, etc.) without the use of a WebView. The solution will be platform-specific, since even the underlying WebView implementations are different for each platform.

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

For Android, so long as the device ships with V8, you can create a new V8 Context via its APIand use that to execute your JavaScript. The device must actually ship with V8. This answermay help you further.

对于 Android,只要设备附带 V8,您就可以通过其 API 创建新的 V8 上下文并使用它来执行您的 JavaScript。该设备必须实际附带 V8。这个答案可能会进一步帮助你。

For iOS, which uses JavaScriptCore, recent developments in iOS7 have been made to allow you load and run arbitrary JavaScript code. Read more here.

对于使用JavaScriptCore 的iOS,最近在 iOS7 中的开发允许您加载和运行任意 JavaScript 代码。 在这里阅读更多

回答by Wesley

I don't know how to use V8, but you can use Rhinolibrary instead. There is no WebView involved too.

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

Download Rhinofirst, unzip it, put the js.jar file under libs folder. It is very small, so you don't need to worry your apk file will be ridiculously large because of this one external jar.

先下载Rhino,解压,把js.jar文件放到libs文件夹下。它非常小,因此您不必担心您的 apk 文件会因为这个外部 jar 文件而大得离谱。

Here is some simple code to execute JavaScript code.

下面是一些执行 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();
}

You can see more details at my post.

您可以在我的帖子中查看更多详细信息。

回答by Angelo

For the Android part. I used J2V8JavaScript library. It is a Java wrapper of Google's V8 JavaScript engine. See herefor more details.

对于安卓部分。我使用了J2V8JavaScript 库。它是 Google 的 V8 JavaScript 引擎的 Java 包装器。请参阅此处了解更多详情。

回答by Pawan Kumar

I found this really nifty open source ECMAScript compliant JS Engine completely written in C called duktape

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

Duktape is an embeddable Javascript engine, with a focus on portability and compact footprint.

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

You'd still have to go through the ndk-jni business, but it's pretty straight forward. Just include the duktape.cand duktape.hfrom the distributable source here(If you don't want to go through the build process yourself) into the jni folder, update the Android.mk and all that stuff.

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

Here's a sample C snippet to get you started.

这是一个示例 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;
}

Good luck!

祝你好运!