Je fais du sport de l'exécution de javascript à partir de Java. Rhino fonctionne très bien pour cela sur le bureau, mais doit se replier à la (lente) en mode interprété sur Android (en raison de dalvik étant pas en mesure d'exécuter le bytecode Java le Rhino JIT compile).
Android a intégré dans le moteur javascript V8, qui est accessible en interne via JNI et devrait donner de bien meilleures performances que les Rhinocéros; toutefois, la seule façon que je peux trouver pour l'accès c'est par l'intermédiaire d'une WebView.
Malheureusement, WebView nécessite un Contexte, et des plantages avec des entrées en phase nationale avec une valeur null contexte, donc je suis incapable de même instancier un mannequin WebView simplement exécuter le code et de retourner le résultat. La nature de mon exercice n'a pas vraiment me permettre de fournir un Contexte pour la WebView, donc je suis en espérant que peut-être il y a quelque chose que je suis surplombant.
Plusieurs de ces V8Threads s'exécuter en parallèle, de sorte qu'il n'est pas vraiment possible (pour autant que je suis au courant) pour ajouter une WebView pour ma mise en page et de le cacher, car je ne crois pas un seul WebView peut exécuter des fonctions dans plusieurs threads.
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+")");
}
}
Idéalement, il doit y avoir une prise en charge pour appeler V8 directement, ou au moins d'exécuter du javascript sans avoir besoin d'une réelle WebView, comme il semble que plutôt maladroit et alambiqué méthode à exécuter du code javascript.
Mise à JOUR
J'ai réarrangé mon code un peu, quoique invisible ici, c'est que maintenant, je suis à l'instanciation de la V8Threads sur le AsyncTasks de onPreExecute() tout en gardant tout le reste dans doInBackground(). Le code source est lu plus tôt dans le programme, il n'est donc pas de manière redondante re-lire pour chaque thread.
Parce que maintenant le V8Thread est instancié sur le Thread de l'INTERFACE utilisateur, je peux la passer à la vue actuelle du Contexte (je suis à l'aide de fragments, donc je ne peux pas juste passer "ce"), de sorte qu'il ne se bloque plus.
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");
}
}
Cependant, lors de l'exécution, logcat crache un par le fil de l'erreur "ne Peut pas obtenir la viewWidth après la première mise en page" et le code javascript ne s'exécute jamais. Je sais que le fil des feux complètement, parce que le "Ici" journal d'un message envoyé. Voici le test() de la fonction dans le code js.
function test()
{
V8Thread.setResult("blah");
}
Travail correctement, "blah" doit afficher jusqu'à quatre fois dans le logcat, mais il ne se présente jamais. Pourrait être mon code source est lu de manière incorrecte, mais j'en doute.
Scanner scan = new Scanner(assetManager.open("pi.js"));
while (scan.hasNextLine()) source += scan.nextLine();
La seule autre chose que je peux imaginer que, en raison de ces erreurs, la webView jamais réellement se déplace à l'exécution du javascript.
Je vais aussi ajouter que pi.js ne contient que javascript, HTML non que ce soit. Cependant, même quand je l'envelopper dans juste assez HTML pour la qualifie comme une page web, toujours pas de chance.