WebView evaluateJavascript行为不可预测

WebView evaluateJavascript行为不可预测,javascript,android,android-webview,Javascript,Android,Android Webview,我试图在WebView中从我的Android代码触发JavaScript函数,但没有成功。(对于这个例子,我已经删除了所有杂乱无章的内容,但最终它需要是一个WebView,所以没有AndroidJSCore) 从我收集的信息来看,如果我只需要单向执行(我的Java代码执行JavaScript代码),我不需要JavaScriptInterface,因此我将WebView设置为: webView.setWebChromeClient(new WebChromeClient() { @

我试图在WebView中从我的Android代码触发JavaScript函数,但没有成功。(对于这个例子,我已经删除了所有杂乱无章的内容,但最终它需要是一个WebView,所以没有AndroidJSCore)

从我收集的信息来看,如果我只需要单向执行(我的Java代码执行JavaScript代码),我不需要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);
webView.loadDataWithBaseURL("", getResources().getString(R.string.test_html),
            "text/html; charset=utf-8", "UTF-8", null);
这意味着当页面加载后,它应该触发JavaScript中的测试函数

这就是它失去我的地方。我尝试了3个不同的测试函数,但没有一个像我期望的那样运行

我从包装在CDATA中的字符串资源加载它们,如下所示:

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);
webView.loadDataWithBaseURL("", getResources().getString(R.string.test_html),
            "text/html; charset=utf-8", "UTF-8", null);
第1版,单引号“测试”

<html>
    <head>
        <script type="text/javascript">
        function test(){
            console.log('test');
        }
        </script>
    </head>
    <body>
    </body>
</html>

功能测试(){
console.log('test');
}
Logcat输出:

D/控制台输出:未捕获引用错误:未定义测试

第2版,双引号“测试”


功能测试(){
控制台日志(“测试”);
}
Logcat输出:

D/控制台输出:函数test(){Console.log(test);}

第3版,双引号“testme”


功能测试(){
console.log(“testme”);
}
Logcat输出:

D/控制台输出:未捕获引用错误:未定义testme

最后一个对我来说特别奇怪,为什么需要定义“testme”?这正是我想发送到日志的内容


关于它为什么这样做以及如何从Android正确执行JavaScript,有什么想法吗?谢谢

是的,所以在我的头撞了它一段时间之后,我发现了为什么经过一些尝试和错误后它不起作用

我不知道为什么,但即使封装在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>

功能测试(){
控制台日志(“测试”);
}
但是这确实有效

<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>

功能测试(){
console.log(\“test\”);
}
当然,当在Java中创建字符串时,编辑器将显示您需要转义双引号,但是当将其作为资源创建时,将其包装在CDATA中,然后在任何时候加载它都不会给出提示

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