Используйте движок JavaScript V8 для запуска JS lib без веб-просмотра

Я разрабатываю компонент JavaScript, который отвечает за выполнение запросов на сервере и отправку результатов в пользовательский интерфейс. Делая это в Javascript, я могу сегодня использовать свой компонент в нескольких типах интерфейса: Android-приложение, приложение iOS, приложение для настольных компьютеров (QT), веб-приложение.

Все эти пользовательские интерфейсы создают экземпляр webview. Поэтому мой компонент запускается, когда пользовательский интерфейс загружает выделенный URL (webview.load( "файл://myfirstWebPage.html" ).

Эта первая веб-страница загружает весь компонент Javascript, и когда это будет сделано, пользовательский интерфейс может сделать некоторый запрос к компоненту Javascript, компонент Javascript сделает запрос на сервер и, когда он получит ответ, отправит его клиенту, (UI Android, UI iOS....)

Эта архитектура отлично работает, но я хотел бы знать , если есть другой способ загрузить компонент Javascript без использования веб-просмотра на каждом клиенте?

Может ли мне помочь двигатель V8?

Спасибо за ваш ответ

Ответ 1

Если я понимаю ваш вопрос, вы ищете способ выполнить javascript на многих платформах (iOS, Android и т.д.) без использования WebView. Решение будет специфичным для платформы, так как даже базовые реализации WebView для каждой платформы различны.

Для Android, пока устройство поставляется с V8, вы можете создать новый контекст V8 через свой API и использовать его для выполнения ваш JavaScript. Устройство должно действительно поставляться с V8. Этот ответ может помочь вам в дальнейшем.

Для iOS, который использует JavaScriptCore, последние разработки в iOS7 были сделаны, чтобы вы могли загружать и запускать произвольный код javascript. Подробнее здесь.

Ответ 2

Я не знаю, как использовать V8, но вместо этого вы можете использовать библиотеку Rhino. Также не задействован WebView.

Загрузите Rhino сначала, разархивируйте его, поместите файл js.jar в папку libs. Это очень мало, поэтому вам не нужно беспокоиться, что ваш файл apk будет смехотворно большим из-за этой внешней банки.

Вот несколько простых кодов для выполнения кода JavaScript.

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

// Every Rhino VM begins with the enter()
// This Context is not Android 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();
}

Вы можете увидеть более подробную информацию на моем сообщении.

Ответ 3

Для части Android. Я использовал J2V8 библиотеку JavaScript. Это Java-оболочка JavaScript-движка Google V8. Подробнее см. здесь.

Ответ 4

Я нашел этот действительно отличный open source совместимый с ECMAScript JS Engine, полностью написанный на C под названием duktape

Duktape - это встраиваемый механизм Javascript с акцентом на переносимость и компактность.

Вам все равно придется заниматься бизнесом ndk-jni, но это довольно прямолинейно. Просто включите duktape.c и duktape.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;
}

Удачи!