Я выполняю javascript из Java. хорошо для этого на настольных компьютерах, но должен вернуться к (медленному) интерпретируемому режиму на Android (из-за того, что dalvik не может выполнить байт-код Java, компилируемый Rhino JIT).
Android имеет встроенный механизм JavaScript V8, который является доступ к нему осуществляется изнутри через JNI, и он должен обеспечивать гораздо лучшую производительность, чем Rhino; однако единственный способ получить доступ к нему, который я могу найти, - это косвенно через WebView.
К сожалению, WebView требует контекста и вылетает с NPE с нулевым контекстом, поэтому я не могу даже создать фиктивный WebView, чтобы просто выполнить код и вернуть результат. Природа моего упражнения на самом деле не позволяет мне предоставить контекст для WebView, поэтому я надеюсь, что, возможно, я что-то
Некоторые из этих потоков V8Thread работают параллельно, поэтому действительно возможно (насколько мне известно) добавить 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");
}
При правильной работе "blah" должно появиться четыре раза в logcat, но никогда не появляется. Может быть, мой исходный код читается неправильно, но я сомневаюсь в этом.
Scanner scan = new Scanner(assetManager.open("pi.js"));
while (scan.hasNextLine()) source += scan.nextLine();
Единственное, что я могу себе представить, это то, что из-за этих вышеупомянутых ошибок webView фактически никогда не выполняет javascript.
Я также добавьте, что pi.js содержит только javascript, без HTML. Однако даже когда я оборачиваю его HTML-кодом, достаточным для того, чтобы он считался веб-страницей, все равно не повезло.