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

Add*_*dev 6 html javascript android webview

我将提出一个我的问题的修改示例来简化这个问题,但我的完整示例的本质是相同的:

我需要在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>
Run Code Online (Sandbox Code Playgroud)

在此示例中,代码假定已调用的已声明函数showRandomValue().所以我需要在执行代码之前注入此函数.这是我要注入的功能:

<script>
function showRandomValue() {
           document.getElementById("demo").innerHTML = Math.random();
      }
</script>
Run Code Online (Sandbox Code Playgroud)

直到现在我在加载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");
Run Code Online (Sandbox Code Playgroud)

这对我很有用,直到我想将targetSdkVersion更新为24.如果我设置targetSdkVersion 24此代码停止工作,因为代码加载时找不到该函数.

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

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

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

webview.addJavascriptInterface(new MyInterface(),"javaInterface");
Run Code Online (Sandbox Code Playgroud)

并在例如中调用其方法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");
    }    
}
Run Code Online (Sandbox Code Playgroud)

使用targetSdkVersion 23编译此代码将起作用,而targetSdkVersion 24将无法显示随机数

gaa*_*gaa 0

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