WebView呼叫JS失敗問題總結
阿新 • • 發佈:2019-01-23
背景說明
最近在專案裡需要在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方法
- 解決跨域問題