我将提供一个修改过的例子来简化这个问题,但是本质上对于我的完整示例来说是相同的:
我需要在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 加载页面(如 loadUrl(String))时,不再持久保存 JavaScript 状态。例如,在调用 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编译,则无法显示随机数。
JavaScriptInterface
似乎会完美地为您工作。如果无法对服务器代码进行更改,那么我认为您现在没有任何可用的解决方案。您可以尝试向Google报告此问题。 - Amrut Bidri