Как запустить JavaScript в Android и передать карту в качестве аргумента

Я пытаюсь запустить JavaScript в Android и обнаружил, Rhino и Duktape предоставляет функциональность для запуска без WebView. Но похоже, что ни один из них не имеет четкого способа передачи переменного числа пар ключ-значение в качестве аргумента в мою функцию js. Аргумент будет выглядеть так:

{"device":"android", "version":"4.4", "country":"US",...}

и сторона JS будет выглядеть

function calculate(param) {
    var country = 'country';
    var device = 'device';

    if (country in param && param[country]=='US') {
        return "a";
    }; 
    if (device in param && param[device]=="android") {
        return "b";
    } else {
        return "c";
    }
}

Есть ли обходной путь?

2 ответа

Если входные данные являются строкой в ​​кодировке JSON, которую вы получаете из других мест вашей программы, вы можете преобразовать ее в анализируемый объект просто как:

duk_push_string(ctx, my_json_argument);
duk_json_decode(ctx, -1);

Декодированное значение останется на вершине стека значений. Вызов декодирования не является "защищенным", поэтому он будет генерировать недопустимые входные данные - если это имеет значение, вы должны обернуть весь анализ аргумента и вызвать, например, в duk_safe_call().

Это быстрее (и безопаснее), чем делать duk_eval_string() особенно если ввод не является полностью доверенным.

Я только что попробовал это, и я получил ожидаемые результаты:

#include "src/duktape.h"

char code[] = "function calculate(param) {"
"    var country = 'country';"
"    var device = 'device';"
"    if (country in param && param[country]=='US') {"
"        return \"a\";"
"    }; "
"    if (device in param && param[device]==\"android\") {"
"        return \"b\";"
"    } else {"
"        return \"c\";"
"    }"
"}"
"calculate({\"device\":\"android\", \"version\":\"4.4\", \"country\":\"US\"});";

int main(int argc, char *argv[]) {
  duk_context *ctx = duk_create_heap_default();
  duk_eval_string(ctx, code);
  printf("result is: %s\n", duk_get_string(ctx, -1));
  duk_destroy_heap(ctx);
  return 0;
}

Скомпилируйте и запустите:

$ gcc duktest.c duktape.c -lm
$ ./a.out 
result is: a

Может быть, ваша проблема не в дуктапе?

Другие вопросы по тегам