如何在android 7中加载html之前在webview中注入javascript脚本

Posted

技术标签:

【中文标题】如何在android 7中加载html之前在webview中注入javascript脚本【英文标题】:How to inject a javascript script in a webview before the html load in android 7 【发布时间】:2017-06-04 03:39:17 【问题描述】:

我将提供我的问题的修改示例以简化此问题,但我的完整示例的本质是相同的:

我需要在 webview 中加载一个 html 代码,该代码假定要声明一些 javascript 函数。示例 HTML 代码:

<html>
<body><h1>JavaScript Math.random()</h1>
<p>A random number:</p>
<p id="demo"></p>
<script>showRandomValue();</script>
</body>
</html>

在本例中,代码假定一个名为showRandomValue() 的已声明函数。所以我需要在代码执行之前注入这个函数。这是我要注入的功能:

<script>
function showRandomValue() 
           document.getElementById("demo").innerHTML = Math.random();
      
</script>

直到现在我在 webview 中加载代码之前都是这样做的:

public static final String JAVASCRIPT_FUNCTION = 
        "javascript:function showRandomValue() \n" +
        "           document.getElementById(\"demo\").innerHTML = Math.random();\n" +
        "      ";
webView.loadUrl(JAVASCRIPT_FUNCTION);
webView.loadData(HTML_CODE, "text/html", "UTF-8");

这对我来说效果很好,直到我想将我的 targetSdkVersion 更新为 24。如果我设置 targetSdkVersion 24,此代码将停止工作,因为在加载代码时找不到该函数。

修改 android WebView 文档我发现了这个:

兼容性说明。面向 N 或更高版本的应用程序,来自空 WebView 的 JavaScript 状态不再在诸如 loadUrl(String) 之类的导航中保持不变。例如,调用 loadUrl(String) 之前定义的全局变量和函数将不会存在于加载的页面中。应用程序应该使用 addJavascriptInterface(Object, String) 来跨导航保存 JavaScript 对象。

我的问题是 addJavascriptInterface 你可以声明一个自定义对象,所以我可以声明:

webview.addJavascriptInterface(new MyInterface(),"javaInterface");

并使用例如javaInterface.getRandomValue() 调用其方法。但是我不能用这个方法声明全局函数。

重要提示:我无法编辑或修改 HTML 代码,因为它来自第三方服务器。

如何让这段代码在 android 7+ 中再次运行?

如果您想测试它,这是完整的示例代码:

public class MainActivity extends Activity 

    private WebView webView;
    String HTML_CODE = "<html>\n" +
            "<body><h1>Hello World</h1>\n" +
            "<p>A random number:</p>\n" +
            "<p id=\"demo\"></p>\n" +
            "<script>showRandomValue();</script>\n" +
            "</body>\n" +
            "</html>";

    public static final String JAVASCRIPT_FUNCTION = "(function showRandomValue() document.getElementById(\"demo\").innerHTML = Math.random();)";

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webview);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("javascript:" + JAVASCRIPT_FUNCTION);
        webView.loadData(HTML_CODE, "text/html", "UTF-8");
        

使用 targetSdkVersion 23 编译此代码将有效,使用 targetSdkVersion 24 将无法显示随机数

【问题讨论】:

你的 minSdk 是什么? 如果您同时更改应用程序代码和服务器代码,JavaScriptInterface 似乎会非常适合您。如果无法对服务器代码进行更改,那么我认为您现在没有任何可用的解决方案。您可以尝试将此问题报告给 Google。 【参考方案1】:

我知道您说过您不能修改 HTML...但是如果您使用预取的内容执行 loadData,我看不出有任何理由反对将您想要的函数注入到脚本标记中的 html 头中。总而言之,你做的事情已经有点老套了。

【讨论】:

以上是关于如何在android 7中加载html之前在webview中注入javascript脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android Webview 中加载网页之前注入 javascript?

Android-WebView中加载本地html的方法

在flutter web中加载html内容?

在webview android中加载本地html文件

Android:如何在 WebView 中加载 html 字符串?

如何在android中的对话框中加载webview