之前在『Android WebView 和 JavaScript 交互』一文中留了一个坑没填,就是当 Android 调用 JavaScript 获取返回值时,返回值是字符串与否也会有不同的情况。
有人可能就有疑惑了,因为文章也同样提到,返回值本身就被限定为 String
类型。
没错,evaluateJavascript()
方法中的 ValueCallback
本身就做了泛型的限定:
@Widget
public class WebView extends AbsoluteLayout implements ViewTreeObserver.OnGlobalFocusChangeListener, ViewGroup.OnHierarchyChangeListener, ViewDebug.HierarchyHandler {
...
public void evaluateJavascript(@NonNull String script, @Nullable ValueCallback<String> resultCallback) {
checkThread();
mProvider.evaluateJavaScript(script, resultCallback);
}
}
那么,假如返回值不为字符串时,会返回什么呢?我们可以动手尝试一下。
比如同样是『Android WebView 和 JavaScript 交互』一文中的例子:
<html>
<script type="text/javascript">
function sum(m, n) {
return m + n
}
</script>
...
</html>
class WebActivity : AppCompatActivity() {
...
private fun checkInt() {
webView.evaluateJavascript("sum(3, 2)") { result ->
Log.d(TAG, result) // Log: 5
}
}
}
我们用 Log
打印出来是 5
,记住它不是数字 5
,而是一个字符串,即 result = "5"
。
再来看看布尔类型:
<html>
<script type="text/javascript">
function checkBoolean() {
return true
}
</script>
...
</html>
class WebActivity : AppCompatActivity() {
...
private fun checkBoolean() {
webView.evaluateJavascript("checkBoolean()") { result ->
Log.e(TAG, result) // Log: true
}
}
}
我们用 Log
打印出来是 true
,记住它不是布尔值 true
,而是一个字符串,即 result = "true"
。
接下来看看对象,用之前在『Android 获取 WebView 选区位置』也有类似的例子:
<html>
<script type="text/javascript">
function checkObj() {
var json = {};
json.name = "json";
return json
}
</script>
...
</html>
class WebActivity : AppCompatActivity() {
...
private fun checkObj() {
webView.evaluateJavascript("checkObj()") { result ->
Log.e(TAG, result) // Log: {"name":"json"}
}
}
}
我们用 Log
打印出来是 {"name":"json"}
,记住它不是 JSON 对象,而是一个字符串,即 result = "{\"name\":\"json\"}"
。
最后,我们看看字符串类型:
<html>
<script type="text/javascript">
function sayHi() {
return "Hi"
}
</script>
...
</html>
class WebActivity : AppCompatActivity() {
...
private fun checkObj() {
webView.evaluateJavascript("sayHi()") { result ->
Log.e(TAG, result) // Log: "Hi"
}
}
}
我们用 Log
打印出来是 "Hi"
,而不是 Hi
,即 result = "\"Hi\""
。
发现没有,当 JavaScript 返回值为字符串时,Android 端会在该字符串前后带上双引号 "
,而当返回值为非字符串时,则会直接转为正常的字符串返回。
这样设计的用意也许是 ValueCallback
的泛型指定为 String
后能够更好的区分返回值的类型,但无疑会给使用者造成使用上的麻烦,所以使用时应多加注意。