Cod*_*gue 45 android android-webview android-4.4-kitkat
我正在尝试在Android 4.4中使用新的evaluateJavascript方法,但我得到的所有内容都是null结果:
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
}
});
Run Code Online (Sandbox Code Playgroud)
如何将结果返回此方法?
更新:更多信息:
setJavascriptEnabled(true);
return 'test';
,return { test: 'this' }
console.log('test');
正在执行罚款.targetSdkVersion
为19:如果您的应用使用WebView设备: Nexus 7和Nexus 5(股票)
Mat*_*unt 65
这个示例中使用了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
}
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
您可能仍希望将解析器用于字符串响应的原因是它被转换为JSON值,这意味着它将用引号括起来.
例如,如果你去了:
mWebView.evaluateJavascript("(function() { return 'this'; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints: "this"
}
});
Run Code Online (Sandbox Code Playgroud)
它会打印出这个字符串,用双引号括起来:"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)
}
});
Run Code Online (Sandbox Code Playgroud)
Cod*_*gue 11
好的,所以事实证明result
这里是Javascript调用的结果 - 好像有人将命令输入Javascript控制台.
所以为了获得结果,它需要包含在一个函数中:
webView1.evaluateJavascript("(function() { return \"this\"; })();", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints 'this'
}
});
Run Code Online (Sandbox Code Playgroud)
这也有效:
webView1.evaluateJavascript("window.variable = \"asd\";", new ValueCallback<String>() {
@Override
public void onReceiveValue(String s) {
Log.d("LogName", s); // Prints asd
}
});
Run Code Online (Sandbox Code Playgroud)
该方法还处理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"}
}
});
Run Code Online (Sandbox Code Playgroud)
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)
}
});
Run Code Online (Sandbox Code Playgroud)
每个人的答案都很棒。我再补充一点。不要像这样使用@JavascripInterface 注释将evaluateJavascript 放在方法中
@JavascriptInterface //this is the right annotation
public void onData(){
mWebView.evaluateJavascript("javascript:executeNext()",null);
}
Run Code Online (Sandbox Code Playgroud)
因为它会阻塞 JavaBridge 线程。如果你想把evaluateJavascript放在里面。用这种方式做
@JavascriptInterface
public void onData(){
mWebView.post(new Runnable() {
@Override
public void run() {
mWebView.evaluateJavascript("javascript:executeNext()",null);
}
});
}
Run Code Online (Sandbox Code Playgroud)
总结@GauntFace 的答案并提供不使用 JSON 解析器的替代解决方案:
如果您的 JS 函数只返回 aString
并且您想知道为什么该字符串在 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"
}
});
Run Code Online (Sandbox Code Playgroud)
(请注意,onReceiveValue
始终提供一个String
while JS 函数可能会返回 a null
,一个 Number 字面量等)
要获得与 JS 中相同的字符串值,如果您 100% 确定您期望String
返回正确的值,则需要对它进行 JSON-unescape,例如:
String unescaped = s.substring(1, s.length() - 1) // remove wrapping quotes
.replace("\\\\", "\\") // unescape \\ -> \
.replace("\\\"", "\""); // unescape \" -> "
Run Code Online (Sandbox Code Playgroud)
但是,请注意,如果 JS 返回正确的,则它s
可能是一个字符串,因此您显然需要将其作为第一步进行检查。"null"
null
if ("null".equals(s)) {
...
} else {
// unescape JSON
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
76770 次 |
最近记录: |