背景说明
最近在项目里需要在WebView调用JS方法,遇到了一些坑,在此记录下来。方便以后查找回顾。
一般来说,如果需要在WebView调用JS方法,只需要进行以下几步:
1、设置WebView支持JS
webSettings.setJavaScriptEnabled(true);
2、加载html文件/url
webView.loadUrl("file:///android_asset/index.html");
或者
webView.loadUrl("www.baidu.com");
3、调用JS方法
// 无参
webView.loadUrl("javascript:helloworld()");
// 有参
webView.loadUrl("javascript:helloworld('" + word + "')");
注意:JS里面的变量需要用”来表示
现在遇到的情况就是:在无参数的时候能够正常调用JS,有参情况无法调用,接下来就一步步来排查。
排查问题
1、首先要让WebView支持JS
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
2、然后传参的时候记得在变量加上”
webView.loadUrl("javascript:helloworld('" + word + "')");
这个时候还是不行,上网查了一下,貌似WebView加载url是异步的,js应该在加载完html后再调用,因此再加上下面这段代码
3、重写onPageFinished方法
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
String word = "test";
webView.loadUrl("javascript:helloworld('" + word + "')");
}
});
这个时候发现还是不行,最后想想,会不会是因为ajax请求有跨域的问题,但是看控制台又没有报错,不管了,先把代码加上
4、解决跨域问题
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
forecastWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);
}else{
try {
Class<?> clazz = forecastWebView.getSettings().getClass();
Method method = clazz.getMethod("setAllowUniversalAccessFromFileURLs", boolean.class);
if (method != null) {
method.invoke(forecastWebView.getSettings(), true);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
由于在sdk > 16以上,也就是4.1以上就能直接设置,但是低于4.1的版本只能通过反射的方式来设置,代码大家看一下就懂了。
最后再Build & Run,发现困扰了很久的调用问题居然被解决了。虽然过程比较曲折,但是也算是学习到了一些经验,因此也把这个过程总结下来。
总结
如果JS调用失败,一般有以下几个解决方案,大家根据实际情况来使用:
- 设置WebView支持JS
- 传参的时候记得变量需要加上”
- 重写onPageFinished方法
- 解决跨域问题