1. 程式人生 > >WebView呼叫JS失敗問題總結

WebView呼叫JS失敗問題總結

背景說明

最近在專案裡需要在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呼叫失敗,一般有以下幾個解決方案,大家根據實際情況來使用:

  1. 設定WebView支援JS
  2. 傳參的時候記得變數需要加上”
  3. 重寫onPageFinished方法
  4. 解決跨域問題