Tengo un programa de Android (Java + html en una vista web). Puedo llamar desde javascript al código Java. Pero al revés dejó de funcionar (después de actualizar en eclipse).
Entonces esto es lo que estoy tratando de hacer
- Hacer una vista web (funcionado)
- llamando en javascript a AndroidFunction.test (); (trabajó)
- la función java test () llamada webView.loadUrl ("javascript: helloBack ()"); (! ya no funciona)
Intenté dejar que funcionara con WebView en MainActivity, pero no funcionó.
MainActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final WebView webView = (WebView)findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
javascr = new Javascript(this, webView);
webView.addJavascriptInterface(javascr, "AndroidFunction");
webView.loadUrl("file:///android_asset/www/index.html");
....
}
Javascript.java
public class Javascript {
Context cont;
WebView webView;
Javascript(Context c, WebView w) {
cont = c;
webView = w;
}
// function called in the javascript by AndroidFunction.test();
public void test() {
// Breaking point!!!
webView.loadUrl("javascript:helloBack()");
}
Error:
03-24 11:47:50.103: W/WebView(21026): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper{41ab68f8} called on Looper{41bb70a8}, FYI main Looper is Looper{41ab68f8})
03-24 11:47:50.103: W/WebView(21026): at android.webkit.WebView.checkThread(WebView.java:2063)
03-24 11:47:50.103: W/WebView(21026): at android.webkit.WebView.loadUrl(WebView.java:794)
03-24 11:47:50.103: W/WebView(21026): at com.example.hellobt.Javascript.test(Javascript.java:24)
03-24 11:47:50.103: W/WebView(21026): at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
03-24 11:47:50.103: W/WebView(21026): at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
03-24 11:47:50.103: W/WebView(21026): at android.os.Handler.dispatchMessage(Handler.java:102)
03-24 11:47:50.103: W/WebView(21026): at android.os.Looper.loop(Looper.java:137)
03-24 11:47:50.103: W/WebView(21026): at android.os.HandlerThread.run(HandlerThread.java:61)
Gracias por la respuesta. Edité la función en mi archivo Javascript así:
private void test(final String s) {
webView.post(new Runnable() {
public void run() {
webView.loadUrl("javascript:" + s + ";");
}
});
System.out.println("javscript done..");
}
javascript
android
android-webview
Johan Hoeksma
fuente
fuente
Respuestas:
El método de JavaScript se ejecuta en un hilo de fondo (es decir, no UI). Debe llamar a todos los métodos relacionados con Android View en el hilo de la interfaz de usuario. Puede lograr lo que necesita con:
mWebView.post(new Runnable() { @Override public void run() { mWebView.loadUrl(...). } });
Que publicará la tarea para que se ejecute en el hilo de la IU.
fuente
En mi caso, no se mostró nada en WebView, así que prefiero otra forma:
runOnUiThread(new Runnable() { @Override public void run() { final WebView webView = (WebView) findViewById(R.id.map); webView.loadDataWithBaseURL(...); } });
fuente
Esto se puede solucionar mediante el método de publicación. Por favor revise el siguiente código.
m_targetView.post(new Runnable() { @Override public void run() { m_targetView.loadUrl("....."); } });
fuente
Versión de Java : debe utilizar la interfaz Runnable y Post to Handler .
webView.post(new Runnable() { @Override public void run() { webView.loadUrl("file:///android_asset/www/index.html"); } });
Versión de Kotlin :
webView.post(new Runnable { webView.loadUrl("file:///android_asset/www/index.html") })
fuente