, который, на самом деле, основан на V8. Он не только включает в себя движок V8, но и весь Node.js доступен.

имаюсь выполнением JavaScript из Java. Rhino очень хорошо работает для этого на настольном компьютере, но вынужден прибегать к (медленному) интерпретируемому режиму на Android (из-за того, что dalvik не может выполнить байт-код Java, который компилирует Rhino JIT).

Android имеет встроенный движок V8 javascript, доступ к которому осуществляется изнутри через JNI и который должен обеспечивать гораздо лучшую производительность, чем Rhino; однако единственный способ найти к нему доступ - это косвенно через WebView.

К сожалению, WebView требуется контекст, и происходит сбой с NPE с нулевым контекстом, поэтому я не могу даже создать фиктивный WebView, чтобы просто выполнить код и вернуть результат. Характер моего упражнения на самом деле не позволяет мне предоставлять контекст для WebView, поэтому я надеюсь, что, может быть, я что-то упускаю.

Некоторые из этих V8Threads работают параллельно, поэтому не представляется возможным (насколько я знаю) добавить WebView в мой макет и скрыть его, поскольку я не верю, что один WebView может выполнять функции в нескольких потоках.

private class V8Thread extends Thread
{
    private WebView webView;
    private String source;

    private double pi;
    private int i, j;

    public V8Thread(int i, int j)
    {
        pi = 0.0;
        this.i = i;
        this.j = j;

        source = "";

        try {
            InputStreamReader isReader = new InputStreamReader(assetManager.open("pi.js"));
            int blah = isReader.read();
            while (blah != -1)
            {
                source += (char)blah;
                blah = isReader.read();
            }

            webView = new WebView(null);
            webView.loadData(source, "text/html", "utf-8");
            webView.getSettings().setJavaScriptEnabled(true);
            webView.addJavascriptInterface(this, "V8Thread");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public double getResult()
    {
        return pi;
    }

    @Override
    public void run() 
    {
        webView.loadUrl("javascript:Androidpicalc("+i+","+j+")");
    }
}

В идеале должен быть какой-то поддерживаемый способ прямого вызова V8 или, по крайней мере, выполнения javascript, не требуя реального WebView, так как он кажется довольно неуклюжим и запутанным методом только для запуска кода javascript.

ОБНОВИТЬ

Я немного перестроил свой код, хотя здесь не видно, что теперь я создаю экземпляры V8Threads в onPreExecute () AsyncTasks, сохраняя все остальное в doInBackground (). Исходный код читается ранее в программе, поэтому он не перечитывается для каждого потока.

Поскольку теперь экземпляр V8Thread создается в потоке пользовательского интерфейса, я могу передать ему контекст текущего представления (я использую фрагменты, поэтому я не могу просто передать его «this»), чтобы он больше не падал.

private class V8Thread extends Thread
{
    private WebView webView;

    private double pi;
    private int i, j;

    public V8Thread(int i, int j)
    {
        pi = 0.0;
        this.i = i;
        this.j = j;

        source = "";

        webView = new WebView(v.getContext());
    }

    @SuppressWarnings("unused")
    public void setResult(String in)
    {
        Log.d("Pi",in);
    }

    public double getResult()
    {
        return pi;
    }

    @Override
    public void run()
    {
        webView.getSettings().setJavaScriptEnabled(true);
        webView.addJavascriptInterface(this, "V8Thread");
        webView.loadData(source, "text/html", "utf-8");
        //webView.loadUrl("javascript:Androidpicalc("+i+","+j+")");
        webView.loadUrl("javascript:test()");
        Log.d("V8Thread","Here");
    }
}

Однако при выполнении logcat выдает по одному на поток сообщения об ошибке «Не удается получить viewWidth после первого макета», и код javascript никогда не выполняется. Я знаю, что поток запускается полностью, потому что отправлено сообщение журнала «Здесь». Вот соответствующая функция test () в коде js.

function test()
{
V8Thread.setResult("blah");
}

Работая правильно, «бла» должен появляться четыре раза в logcat, но он никогда не появляется. Может быть, мой исходный код читается неправильно, но я сомневаюсь в этом.

Scanner scan = new Scanner(assetManager.open("pi.js"));
while (scan.hasNextLine()) source += scan.nextLine();

Единственное, что я могу себе представить, это то, что из-за этих вышеупомянутых ошибок webView на самом деле никогда не справляется с выполнением javascript.

Я также добавлю, что pi.js содержит только javascript, но не HTML. Тем не менее, даже когда я обертываю его в достаточное количество HTML-кода, чтобы его можно было считать веб-страницей, мне все равно не повезло.

Ответы на вопрос(5)

Ваш ответ на вопрос