WebView evaluateJavascript 行为不可预测
WebView evaluateJavascript behaving unpredictably
我试图从 WebView 中的 Android 代码触发 JavaScript 函数,但未成功。 (我已经删除了这个例子的所有混乱,但最终它需要是一个 WebView,所以没有 AndroidJSCore)
根据我收集到的信息,如果我只想以一种方式执行(我的 Java 代码执行 Java 脚本代码),我不需要 JavaScriptInterface 所以我已经设置我的 WebView 是这样的:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d("Console output", consoleMessage.message());
return super.onConsoleMessage(consoleMessage);
}
});
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("test();", null);
} else {
webView.loadUrl("javascript:test();");
}
}
});
webView.getSettings().setJavaScriptEnabled(true);
这意味着当页面加载后,它应该触发 JavaScript 中的 test 函数。
这就是它失去我的地方。我尝试了 3 个不同的 test 函数并且 none 表现得像我期望的那样。
我从包裹在 CDATA 中的字符串资源加载它们,如下所示:
webView.loadDataWithBaseURL("", getResources().getString(R.string.test_html),
"text/html; charset=utf-8", "UTF-8", null);
版本 1,单引号 'test'
<html>
<head>
<script type="text/javascript">
function test(){
console.log('test');
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: Uncaught ReferenceError: test is not defined
版本 2,双引号 "test"
<html>
<head>
<script type="text/javascript">
function test(){
console.log("test");
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: function test(){ console.log(test); }
版本 3,双引号 "testme"
<html>
<head>
<script type="text/javascript">
function test(){
console.log("testme");
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: Uncaught ReferenceError: testme is not defined
最后一个对我来说特别奇怪,为什么 "testme" 需要定义?这正是我要发送到日志的内容?
关于它为什么这样做以及如何从 Android 正确执行 Java 脚本的任何想法?谢谢!
是的,所以在反复思考了一段时间后,我发现了为什么它在反复试验后不起作用。
我不知道为什么,但即使封装在 CDATA 包装器中 loadDataWithBaseURL 也不喜欢单引号或双引号,在其第二个参数的任何位置。
所以,这行不通
<html>
<head>
<script type="text/javascript">
function test(){
console.log("test");
}
</script>
</head>
<body>
</body>
</html>
但是这确实有效
<html>
<head>
<script type=\"text/javascript\">
function test(){
console.log(\"test\");
}
</script>
</head>
<body>
</body>
</html>
当然,当在 Java 中创建字符串时,编辑器会显示您需要转义双引号,但是当将其创建为资源时,将其包装在 CDATA 中然后在任何时候加载它都不会提个醒。
所以,希望有一天这对某人有用。
我试图从 WebView 中的 Android 代码触发 JavaScript 函数,但未成功。 (我已经删除了这个例子的所有混乱,但最终它需要是一个 WebView,所以没有 AndroidJSCore)
根据我收集到的信息,如果我只想以一种方式执行(我的 Java 代码执行 Java 脚本代码),我不需要 JavaScriptInterface 所以我已经设置我的 WebView 是这样的:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
Log.d("Console output", consoleMessage.message());
return super.onConsoleMessage(consoleMessage);
}
});
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("test();", null);
} else {
webView.loadUrl("javascript:test();");
}
}
});
webView.getSettings().setJavaScriptEnabled(true);
这意味着当页面加载后,它应该触发 JavaScript 中的 test 函数。
这就是它失去我的地方。我尝试了 3 个不同的 test 函数并且 none 表现得像我期望的那样。
我从包裹在 CDATA 中的字符串资源加载它们,如下所示:
webView.loadDataWithBaseURL("", getResources().getString(R.string.test_html),
"text/html; charset=utf-8", "UTF-8", null);
版本 1,单引号 'test'
<html>
<head>
<script type="text/javascript">
function test(){
console.log('test');
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: Uncaught ReferenceError: test is not defined
版本 2,双引号 "test"
<html>
<head>
<script type="text/javascript">
function test(){
console.log("test");
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: function test(){ console.log(test); }
版本 3,双引号 "testme"
<html>
<head>
<script type="text/javascript">
function test(){
console.log("testme");
}
</script>
</head>
<body>
</body>
</html>
Logcat 输出:
D/Console output: Uncaught ReferenceError: testme is not defined
最后一个对我来说特别奇怪,为什么 "testme" 需要定义?这正是我要发送到日志的内容?
关于它为什么这样做以及如何从 Android 正确执行 Java 脚本的任何想法?谢谢!
是的,所以在反复思考了一段时间后,我发现了为什么它在反复试验后不起作用。
我不知道为什么,但即使封装在 CDATA 包装器中 loadDataWithBaseURL 也不喜欢单引号或双引号,在其第二个参数的任何位置。
所以,这行不通
<html>
<head>
<script type="text/javascript">
function test(){
console.log("test");
}
</script>
</head>
<body>
</body>
</html>
但是这确实有效
<html>
<head>
<script type=\"text/javascript\">
function test(){
console.log(\"test\");
}
</script>
</head>
<body>
</body>
</html>
当然,当在 Java 中创建字符串时,编辑器会显示您需要转义双引号,但是当将其创建为资源时,将其包装在 CDATA 中然后在任何时候加载它都不会提个醒。
所以,希望有一天这对某人有用。