2017-09-12 3 views
0

Je tente de créer un service Android qui effectue une tâche en utilisant JavaScript. Je suis tombé sur this post qui décrit comment exécuter du code JavaScript à l'intérieur d'un WebView dans un service en utilisant le WindowManager. Je suis en mesure de créer un WebView avec un fichier .html et .js sans problème. C'est une fois que j'essaie de transmettre des données à partir du service android .java au WebView que je rencontre un problème.impossible d'exécuter le code javascript dans Android WebView à partir du service

J'ai essayé faire de cette façon:

final WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 
... 
wv = new WebView(this); 
wv.setWebViewClient(new WebViewClient()); 
wv.getSettings().setJavaScriptEnabled(true); 
wv.loadUrl("file:///android_asset/www/test.html"); 
windowManager.addView(wv, params); // params set using method from linked post above 
wv.evaluateJavascript("console.log('hello');", null); 
wv.loadUrl("javascript:console.log('blah')"); 

Ni l'appel à evaluateJavascript() ni loadUrl() semblent avoir aucun effet sur la WebView (j'accéder à la console à l'aide des outils de développement de chrome).

J'ai testé que dans test.html je peux ajouter un tag <script> et le texte de sortie à la console sans problème.

J'ai également essayé d'appeler les fonctions avant d'ajouter la vue en vain.

+0

Je recommanderais d'utiliser un interpréteur JavaScript pour cela, comme [duktape] (https://github.com/square/duktape-android). – CommonsWare

+0

@CommonsWare La raison pour laquelle je ne suis pas est que mon code utilise différentes capacités de navigateur que je devrais réimplémenter si j'utilisais quelque chose comme duktape (pour autant que je sache) –

+0

Donc ce que je comprends ce que vous voulez c'est charger test.html et exécutez du code JS? – Steven

Répondre

1

Quel type de données voulez-vous transmettre à Javascript? Vous pouvez utiliser le WebView.addJavascriptInterface() pour "Plantez" des méthodes sur le document HTML afin que vous puissiez les appeler à partir de Javascript, invoquer en natif et retourner les données à Javascript. Cela aidera-t-il?

+0

Je veux essentiellement passer le travail à faire au code javascript (peut-être plusieurs fois) du code natif .. Il ne semble pas que la méthode la plus propre pour le code javascript soit de demander le code natif mais ça ressemble à ça peut être la seule option. Je cherchais à utiliser un CompletableFuture mais cela nécessiterait de cibler <10% des appareils actifs sur le Play Store. –

+1

Je peux vous dire ce que Cordova est en train de faire. Je ne l'aime pas, mais ça peut t'aider. Si vous voulez que JS fasse quelque chose à partir de Java, vous pouvez appeler WebView.setNetworkAvailable (value). celui-ci déclenchera l'événement 'online' ou 'offline' de Javascript (en fonction de la valeur). Ajoutez un écouteur dans JS à cela (document.addEventListener ('online')) - en invoquant une méthode qui a accès à l'interface JS mentionnée ci-dessus. C'est essentiellement comment il est mis en œuvre dans Cordova pour Android. yaiks ... – oriharel

+0

Je n'aime pas ça du tout! suppose que je vais devoir acquiescer compte tenu de la nature non conventionnelle de ce que je suis en train de faire. –

0

Si vous essayez d'exécuter ceci à partir d'un Service, vous devrez publier un Runnable sur le thread UI. Lire le document pour evaluateJavascript()

Il indique explicitement qu'il doit être appelé sur le thread UI. Je pense que vous pouvez simplement faire:

wv.post(new Runnable(){ 
     @Override public void run() 
     { 
      wv.evaluateJavascript(); 
     } 
    }); 

À part cela, devriez-vous inclure des étiquettes?

+0

Je n'ai pas fait de développement Android depuis longtemps mais d'après ce que je comprends en utilisant le code ci-dessus, 'valuJavascript()' serait appelé à partir d'un thread non principal. J'ai essayé d'utiliser votre technique (ne fonctionnait pas) et j'ai ensuite essayé de cette façon: https://stackoverflow.com/a/6630052/5186877 pour appeler la méthode à partir du thread de l'interface utilisateur, mais il ne semble pas non plus fonctionner. –

+0

View.post() est une méthode pratique utilisée spécifiquement pour publier sur le thread UI. https://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable) Je ne suis pas familier avec evaluateJavascript spécifiquement. On dirait que vous faites quelque chose de mal si vous comptez sur WebView pour quoi que ce soit. –

+0

Je viens de me rendre compte que vous chargiez l'URL à partir des ressources. Vous pouvez essayer WebView.loadData ("htmlString", "text/html", null); –