我正在尝试在Android 4.4中使用新的evaluateJavascript方法,但我得到的所有内容都是空结果:
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
}
});
如何将结果返回此方法?
更新:更多信息:
setJavascriptEnabled(true);
return 'test';
,return { test: 'this' }
console.log('test');
正在执行。targetSdkVersion
设置为19
醇>
设备:Nexus 7和Nexus 5(股票)
答案 0 :(得分:58)
此示例中使用了evaluateJavascript方法的示例:
https://github.com/GoogleChrome/chromium-webview-samples/tree/master/jsinterface-example
基本上,如果您在WebView中执行的javascript返回一个值,它将在回调中传递。
需要注意的是,OnReceiveValue中返回的String是JSON值,JSON对象或JSON数组,具体取决于您返回的内容。
需要注意的是,如果您返回单个值,则需要在JSON阅读器上使用setLenient(true)才能使其正常工作。
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
}
}
}
});
}
您可能仍希望将解析器用于字符串响应的原因是它被转换为JSON值,这意味着它将用引号括起来。
例如,如果你去了:
mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: "this"
}
});
它将打印字符串,用双引号括起来:“this”。
其他值得注意的例子:
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
}
});
mWebView.evaluateJavascript("(function() { return ''; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints "" (Two double quotes)
}
});
答案 1 :(得分:10)
好的,所以事实证明result
这里是Javascript调用的结果 - 好像有人将命令输入Javascript控制台。
因此,为了获得结果,需要将其包含在函数中:
webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints 'this'
}
});
这也有效:
webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints asd
}
});
该方法还处理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"}
}
});
答案 2 :(得分:7)
AndroidJSCore是评估不使用WebView的JavaScript的好选择。
如果你想坚持使用WebView并且需要在早期版本的Android(4+)上评估JavaScript,这里有一个小库:
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)
}
});
答案 3 :(得分:3)
总结@GauntFace的答案,并在不使用JSON解析器的情况下提供替代解决方案:
如果你的JS函数只返回String
并且你想知道为什么字符串在Java中被破坏了,那是因为它是JSON转义的。
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"
}
});
(请注意onReceiveValue
始终提供String
,而JS函数可能返回null
,数字文字等。)
要获得与JS中相同的字符串值,如果您100%确定您期望返回正确的String
,则需要JSON-unescape它,例如:< / p>
String unescaped = s.substring(1, s.length() - 1) // remove wrapping quotes
.replace("\\\\", "\\") // unescape \\ -> \
.replace("\\\"", "\""); // unescape \" -> "
但是,请注意,如果JS返回正确的s
,"null"
可能是字符串null
,因此您显然需要将其作为第一步检查。
if ("null".equals(s)) {
...
} else {
// unescape JSON
}
答案 4 :(得分:2)
每个人的回答都很好。我再增加一点。不要像这样用@JavascripInterface注释将评估Javascript放在方法中
@JavascripInterface
public void onData(){
mWebView.evaluateJavascript("javascript:executeNext()",null);
}
因为它将阻塞JavaBridge线程。 如果您要在其中放入评估Javascript。用这种方式做
@JavascripInterface
public void onData(){
mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.evaluateJavascript("javascript:executeNext()",null);
}
});
}
答案 5 :(得分:0)
重要提示:
在调用evaluateJavascript
之前,您必须为WebView启用JavaScript。否则您将无法获得结果。
WebSettings settings = yourWebview.getSettings();
settings.setJavaScriptEnabled(true);