studio propiedades examples example app javascript android webview

propiedades - Funciones de JavaScript de Android Calling en WebView



webview android java (6)

A partir de kitkat, utilice el método evalJavascript en lugar de loadUrl para llamar a las funciones de javascript como a continuación

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { webView.evaluateJavascript("enable();", null); } else { webView.loadUrl("javascript:enable();"); }

Estoy intentando llamar a algunas funciones de javascript que se encuentran en una página html ejecuta dentro de una vista android webview . Bastante simple lo que el código intenta hacer a continuación: desde la aplicación de Android, llame a una función de javascript con un mensaje de prueba, que a su vez llama a una función de Java en la aplicación de Android que muestra el mensaje de prueba a través de un brindis.

La función javascript ve así:

function testEcho(message){ window.JSInterface.doEchoTest(message); }

Desde la vista web, he intentado llamar a javascript las siguientes maneras sin suerte:

myWebView.loadUrl("javascript:testEcho(Hello World!)"); mWebView.loadUrl("javascript:(function () { " + "testEcho(Hello World!);" + "})()");

He habilitado javascript en la vista WebView

myWebView.getSettings().setJavaScriptEnabled(true); // register class containing methods to be exposed to JavaScript myWebView.addJavascriptInterface(myJSInterface, "JSInterface");

Y heres la clase de Java

public class JSInterface{ private WebView mAppView; public JSInterface (WebView appView) { this.mAppView = appView; } public void doEchoTest(String echo){ Toast toast = Toast.makeText(mAppView.getContext(), echo, Toast.LENGTH_SHORT); toast.show(); } }

He pasado mucho tiempo buscando en Google para ver qué puedo estar haciendo mal. Todos los ejemplos que he encontrado utilizan este enfoque. ¿Alguien ve algo mal aquí?

Edición: hay varios otros archivos javascript externos que están siendo referenciados y usados ​​en el html , ¿podrían ser el problema?


Descubrí cuál era el problema: comillas faltantes en el parámetro testEcho (). Así es como conseguí la llamada al trabajo:

myWebView.loadUrl("javascript:testEcho(''Hello World!'')");


He creado un bonito envoltorio para llamar a los métodos de JavaScript; también muestra errores de JavaScript en el registro:

private void callJavaScript(String methodName, Object...params){ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("javascript:try{"); stringBuilder.append(methodName); stringBuilder.append("("); for (int i = 0; i < params.length; i++) { Object param = params[i]; if(param instanceof String){ stringBuilder.append("''"); stringBuilder.append(param); stringBuilder.append("''"); } if(i < params.length - 1){ stringBuilder.append(","); } } stringBuilder.append(")}catch(error){Android.onError(error.message);}"); webView.loadUrl(stringBuilder.toString()); }

Necesitas agregar esto también:

private class WebViewInterface{ @JavascriptInterface public void onError(String error){ throw new Error(error); } }

Y agrega esta interfaz a tu webview:

webView.getSettings().setJavaScriptEnabled(true); webView.addJavascriptInterface(new WebViewInterface(), "AndroidErrorReporter");


Modificación de la respuesta de @Ilya_Gazman.

private void callJavaScript(WebView view, String methodName, Object...params){ StringBuilder stringBuilder = new StringBuilder(); stringBuilder.append("javascript:try{"); stringBuilder.append(methodName); stringBuilder.append("("); String separator = ""; for (Object param : params) { stringBuilder.append(separator); separator = ","; if(param instanceof String){ stringBuilder.append("''"); } stringBuilder.append(param); if(param instanceof String){ stringBuilder.append("''"); } } stringBuilder.append(")}catch(error){console.error(error.message);}"); final String call = stringBuilder.toString(); Log.i(TAG, "callJavaScript: call="+call); view.loadUrl(call); }

creará correctamente llamadas JS por ejemplo

callJavaScript(mBrowser, "alert", "abc", "def"); //javascript:try{alert(''abc'',''def'')}catch(error){console.error(error.message);} callJavaScript(mBrowser, "alert", 1, true, "abc"); //javascript:try{alert(1,true,''abc'')}catch(error){console.error(error.message);}

Tenga en cuenta que los objetos no se pasarán correctamente, pero puede serializarlos antes de pasar como argumento.

También he cambiado donde va el error, lo he desviado al registro de la consola que puede ser escuchado por:

webView.setWebChromeClient(new CustomWebChromeClient());

y cliente

class CustomWebChromeClient extends WebChromeClient { private static final String TAG = "CustomWebChromeClient"; @Override public boolean onConsoleMessage(ConsoleMessage cm) { Log.d(TAG, String.format("%s @ %d: %s", cm.message(), cm.lineNumber(), cm.sourceId())); return true; } }


Sí tienes el error de sintaxis. Si desea obtener sus errores de Javascript y las declaraciones de impresión en su logcat, debe implementar el onConsoleMessage(ConsoleMessage cm) en su WebChromeClient. Da los rastros completos de la pila como la consola web (elemento Inspeccionar). Aquí está el método.

public boolean onConsoleMessage(ConsoleMessage cm) { Log.d("ShowMote", cm.message() + " -- From line " + cm.lineNumber() + " of " + cm.sourceId() ); return true; }

Después de la implementación, obtendrá sus errores de Javascript e instrucciones de impresión ( console.log ) en su logcat.


public void run(final String scriptSrc) { webView.post(new Runnable() { @Override public void run() { webView.loadUrl("javascript:" + scriptSrc); } }); }