¿Cómo funciona evaluateJavascript?

Estoy tratando de usar el nuevo método evaluateJavascript en Android 4.4, pero todo lo que nunca volver es un resultado nulo:

webView1.evaluateJavascript("return \"test\";", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Log is written, but s is always null } }); 

¿Cómo devuelvo un resultado a este método?

Actualización: Poco más información:

  1. Tengo el permiso de acceso a Internet
  2. Tengo setJavascriptEnabled(true);
  3. Secuencia apóstrofe probada: return 'test'; ,
  4. Objeto JS probado: return { test: 'this' }
  5. console.log('test'); Se está ejecutando bien.
  6. Establezca targetSdkVersion en 19 según: Si su aplicación utiliza WebView

Dispositivos: Tanto Nexus 7 como Nexus 5 (Stock)

Hay un ejemplo del método evaluateJavascript que se está utilizando en este ejemplo:

https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example

Esencialmente, si el javascript que ejecuta en el WebView devuelve un valor que se pasará en la devolución de llamada.

Lo más importante a destacar es que la cadena devuelta en OnReceiveValue es un valor JSON, un objeto JSON o una matriz JSON dependiendo de lo que devuelva.

Lo que hay que tener en cuenta es que si devuelves un solo valor, debes usar setLenient (true) en un lector JSON para que funcione.

  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // In KitKat+ you should use the evaluateJavascript method mWebView.evaluateJavascript(javascript, new ValueCallback<String>() { @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public void onReceiveValue(String s) { JsonReader reader = new JsonReader(new StringReader(s)); // Must set lenient to parse single values reader.setLenient(true); try { if(reader.peek() != JsonToken.NULL) { if(reader.peek() == JsonToken.STRING) { String msg = reader.nextString(); if(msg != null) { Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_LONG).show(); } } } } catch (IOException e) { Log.e("TAG", "MainActivity: IOException", e); } finally { try { reader.close(); } catch (IOException e) { // NOOP } } } }); } 

La razón por la que todavía puede utilizar un analizador para una respuesta de cadena es que se convierte en un valor JSON, lo que significa que será envuelto en comillas.

Por ejemplo si fuiste:

 mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints: "this" } }); 

Se imprimirá la cadena de este, envuelto en comillas dobles: "esto".

Otros ejemplos dignos de mención:

 mWebView.evaluateJavascript("(function() { return null; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints the string 'null' NOT Java null } }); mWebView.evaluateJavascript("(function() { })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); //s is Java null } }); 

Aceptar, por lo que resulta que el result aquí es el resultado de la llamada Javascript – como si estuviera ingresando el comando en una consola de Javascript.

Así que para obtener un resultado, tiene que ser envuelto en una función:

 webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints 'this' } }); 

Esto también funcionará:

 webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints asd } }); 

El método también maneja objetos Javascript:

 webView1.evaluateJavascript("(function() { return { var1: \"variable1\", var2: \"variable2\" }; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // Prints: {"var1":"variable1","var2":"variable2"} } }); 

AndroidJSCore es una buena alternativa para evaluar JavaScript que no utiliza un WebView.

Si quieres seguir con WebView y necesitas evaluar JavaScript en versiones anteriores de Android (4+), aquí hay una pequeña biblioteca:

https://github.com/evgenyneu/js-evaluator-for-android

 jsEvaluator.evaluate("put your JavaScript code", new JsCallback() { @Override public void onResult(final String result) { // get result here (optional) } }); 

Para resumir la respuesta de @GauntFace y proporcionar una solución alternativa sin utilizar JSON parser:

Si su función JS devuelve sólo una String y usted se está preguntando por qué la cadena se mutila en Java, es porque es JSON-escapada.

 mWebView.evaluateJavascript("(function() { return 'Earvin \"Magic\" Johnson'; })();", new ValueCallback<String>() { @Override public void onReceiveValue(String s) { Log.d("LogName", s); // expected: s == Earvin "Magic" Johnson // actual: s == "Earvin \"Magic\" Johnson" } }); 

(Tenga en cuenta que onReceiveValue siempre proporciona una String mientras que la función JS puede devolver un null , un número literal, etc.)

Para obtener el valor de cadena igual que en JS, si estás 100% seguro de que esperas una String correcta devuelta, necesitarás JSON-unescape, por ejemplo así:

 String unescaped = s.substring(1, s.length() - 1) // remove wrapping quotes .replace("\\\\", "\\") // unescape \\ -> \ .replace("\\\"", "\""); // unescape \" -> " 

Sin embargo, tenga en cuenta que s puede ser una cadena "null" si JS devuelve null adecuado, por lo que obviamente necesita comprobar que como el primer paso.

 if ("null".equals(s)) { ... } else { // unescape JSON } 
  • Vista web de Android: detección de desplazamiento
  • Detectar error de vista Web y mostrar mensaje
  • ¿Cómo desplazar la vista web horizontalmente dentro de ViewPager?
  • Directamente poner código html en un WebView (Android)
  • AdjustResize no funciona después de despedir el teclado haciendo clic en el teclado exterior
  • Android webview + javascript no mostrar la salida en android 4.0.x, 3.x
  • Inicio de sesión de Twitter utilizando WebView
  • Las imágenes se cargan más rápido en la vista web
  • cómo mostrar la vista web como OverviewMode (completamente alejado) en android? ¿cómo?
  • ¿Cómo configurar el desplazamiento perfomance para webview?
  • ¿Cualquier manera de agarrar un icono de la insignia del URL del Web site, programmatically?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.