1. 程式人生 > >完美解決Android的WebView載入失敗(404,500),顯示的自定義檢視

完美解決Android的WebView載入失敗(404,500),顯示的自定義檢視

完美解決Android的WebView載入失敗(404,500),顯示的自定義檢視

好多朋友會在Android開發過程中遇到使用WebView載入html頁面出現404,500等錯誤頁面,也有好多人想自定義這個錯誤頁面,但是在6.0之前,大家覺得自定義錯誤頁面就不好處理了;
之前一直使用在WebView載入時,根據onReceivedError() 判斷網頁是否載入成功,然後做相應的操作,但是最後發現,在一些情況下,html頁面載入失敗了,onReceivedError()方法卻並沒有執行。
最後進過努力,想出了一個比較笨,但是我又覺得比較有效的方法。下面來給大家簡單說一說:
不知道大家發現沒有,在所有的載入錯誤的html頁面中,html的標題title可能都會包含錯誤資訊,比如說“error”,這樣的話我們就可以在這個html的標題title上做文章了。
1.先給大家說說怎麼獲取這個html的標題title


(1).Android應用開發的時候使用WebView這個元件的過程中可能會接觸到WebViewClient與WebChromeClient,那麼這兩個類到底有什麼不同呢
WebViewClient主要幫助WebView處理各種通知、請求事件的,比如:

        onLoadResource
        onPageStart
        onPageFinish
        onReceiveError
        onReceivedHttpAuthRequest

    WebChromeClient主要輔助WebView處理Javascript的對話方塊、網站圖示、網站title、載入進度等比如
        onCloseWindow(關閉WebView)
        onCreateWindow()
        onJsAlert (WebView上alert無效,需要定製WebChromeClient處理彈出)
        onJsPrompt
        onJsConfirm
        onProgressChanged
        onReceivedIcon
        onReceivedTitle
看上去他們有很多不同,實際使用的話,如果你的WebView只是用來處理一些html的頁面內容,只用WebViewClient就行了,如果需要更豐富的處理效果,
比如JS、進度條等,就要用到WebChromeClient。
(2).我們可以看到在 WebChromeClient 中有一個方法 onReceivedTitle() ,這個方法就是用來獲取html頁面的標題title的回撥。

**2.我們在 WebChromeClient 中的 onReceivedTitle() 方法裡判斷html頁面的標題中是否含有 “error” ,如果有,則證明html載入失敗,設定載入失敗的標記,讓在 WebViewClient 的完成是回
調的 onPageFinish() 方法裡顯示自定義的載入失敗的頁面**

程式碼如下:

    WebSettings webSettings = webView.getSettings();
    //設定WebView屬性,能夠執行Javascript指令碼
    webSettings.setJavaScriptEnabled(true);
    //設定可以訪問檔案
    webSettings.setAllowFileAccess(true);
    webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);


    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            view.loadUrl(url);
            return true;
        }

        /**
         * 網頁頁面開始載入的時候,執行的回撥方法
         * @param view
         * @param url
         * @param favicon
         */
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {//網頁頁面開始載入的時候
            emptyView.setEmptyView(EmptyView.EMPTY_LOADING);//初始化一個顯示正在載入的檢視
            rl_detail.setVisibility(View.VISIBLE);
            rl_detail.removeAllViews();
            rl_detail.addView(emptyView);//在載入頁面開始的時候顯示一個正在載入的檢視,
            webView.setEnabled(false);// 當載入網頁的時候將網頁進行隱藏
            ll_container_btn.setVisibility(View.GONE);
            btn_collect.setVisibility(View.GONE);
            super.onPageStarted(view, url, favicon);
        }

        /**
         * 網頁載入結束的時候執行的回撥方法
         * @param view
         * @param url
         */
        @Override
        public void onPageFinished(WebView view, String url) {//網頁載入結束的時候
            if (!loadError) {//當網頁載入成功的時候判斷是否載入成功
                rl_detail.setVisibility(View.GONE);//載入成功的話,則隱藏掉顯示正在載入的檢視,顯示載入了網頁內容的WebView
                webView.setEnabled(true);
                ll_container_btn.setVisibility(View.VISIBLE);
                btn_collect.setVisibility(View.VISIBLE);
            } else { //載入失敗的話,初始化頁面載入失敗的圖,然後替換正在載入的檢視頁面
                rl_detail.removeAllViews();
                emptyView.setEmptyView(EmptyView.EMPTY_EMPTY, "您找的頁面暫時走丟了...");
                rl_detail.addView(emptyView);
            }

        }


        /**
         * 頁面載入錯誤時執行的方法,但是在6.0以下,有時候會不執行這個方法
         * @param view
         * @param errorCode
         * @param description
         * @param failingUrl
         */
        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
            super.onReceivedError(view, errorCode, description, failingUrl);
            loadError = true;
        }


    });

    webView.setWebChromeClient(new WebChromeClient(){
        /**
         * 當WebView載入之後,返回 HTML 頁面的標題 Title
         * @param view
         * @param title
         */
        @Override
        public void onReceivedTitle(WebView view, String title) {
            //判斷標題 title 中是否包含有“error”欄位,如果包含“error”欄位,則設定載入失敗,顯示載入失敗的檢視
          if(!TextUtils.isEmpty(title)&&title.toLowerCase().contains("error")){
              loadError = true;
          }
        }
    });
    webView.loadUrl(url);