Android utiliza V8 sin WebView

Estoy haciendo ejercicio ejecutando javascript desde Java. Rhino funciona muy bien para esto en el escritorio, pero tiene que recurrir al modo interpretado (lento) en Android (debido a que Dalvik no puede ejecutar el código de bytes Java que compila Rhino JIT).

Android tiene su motor V8 javascript incorporado al que se accede internamente a través de JNI y debería ofrecer un rendimiento mucho mejor que Rhino; sin embargo, la única forma en que puedo encontrar para acceder es indirectamente a través de un WebView.

Desafortunadamente, WebView requiere un contexto y se bloquea con NPE con un contexto nulo, por lo que ni siquiera puedo crear una instancia de WebView ficticio para simplemente ejecutar el código y devolver el resultado. La naturaleza de mi ejercicio realmente no me permite proporcionar un Contexto para WebView, así que espero que haya algo que estoy pasando por alto.

Varios de estos V8Threads se ejecutan en paralelo, por lo que no es realmente factible (que yo sepa) agregar un WebView a mi diseño y ocultarlo, ya que no creo que un solo WebView pueda ejecutar funciones en múltiples hilos. @

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+")");
    }
}

De hecho, debe haber alguna forma admitida de llamar a V8 directamente, o al menos ejecutar javascript sin requerir un WebView real, ya que parece un método bastante complicado y complicado para ejecutar el código javascript.

ACTUALIZA

He reorganizado un poco mi código, aunque aquí no se ve que ahora estoy instanciando los V8Threads en onPreExecute () de AsyncTasks mientras mantengo todo lo demás en doInBackground (). El código fuente se lee anteriormente en el programa, por lo que no se vuelve a leer de forma redundante para cada subproceso.

Porque ahora el V8Thread se instancia en el UI Thread, puedo pasarle el Contexto de la vista actual (estoy usando fragmentos, así que no puedo pasarlo "esto"), por lo que ya no se bloquea.

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");
    }
}

Sin embargo, al ejecutar, logcat escupe uno por subproceso del error "No se puede obtener el ancho de vista después del primer diseño" y el código javascript nunca se ejecuta. Sé que el hilo se dispara por completo, porque se envía el mensaje de registro "Aquí". Aquí está la función test () relevante en el código js.

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

Trabajando correctamente, "bla" debería aparecer cuatro veces en logcat, pero nunca aparece. Podría ser que mi código fuente se lea incorrectamente, pero lo dudo.

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

La única otra cosa que puedo imaginar es que debido a estos errores antes mencionados, el webView nunca llega a ejecutar el javascript.

También agregaré que pi.js contiene solo javascript, no HTML en absoluto. Sin embargo, incluso cuando lo envuelvo en suficiente HTML para que califique como una página web, todavía no hay suerte.

Respuestas a la pregunta(5)

Su respuesta a la pregunta