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 中然后在任何时候加载它都不会提个醒。

所以,希望有一天这对某人有用。