天天看點

Android控件(webview)

1.WebView的初始化

WebView mWebView =(WebView)findViewById(R.id.show_webView); 
mWebView.loadUrl(Consts.WEB_URL_BAIDU); // WEB_URL_BAIDU =“https://www.baidu.com/” ```

           

2.WebView的三個基本元件

2.1WebSettings(做各種設定)

  • 擷取設定
WebSettings webSettings = mWebView .getSettings();
           
  • 常見設定:
// JS處理
setJavaScriptEnabled(真); //支援JS 
setPluginsEnabled(真); //支援插件
setJavaScriptCanOpenWindowsAutomatically(真); //支援通過JS打開新視窗//縮放處理setUseWideViewPort(真); //将圖檔調整到适合網頁流量的大小setLoadWithOverviewMode(真); //縮放至螢幕的大小setSupportZoom(真); //支援縮放,預設為真。是下面那個的前提。

setBuiltInZoomControls(真); //設定内置的縮放控件。這個取決于setSupportZoom(),若setSupportZoom(false),則該WebView不可縮放,這個不管縮放,什麼都不能縮放。
setDisplayZoomControls(假); //隐藏原生的縮放控件

//内容布局
setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支援内容重新布局
supportMultipleWindows(); //多視窗

//檔案緩存
setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉網頁視圖中緩存
setAllowFileAccess(真); //設定可以通路檔案

//其他設定
setNeedInitialFocus(真); //當的WebView調用requestFocus的時為網頁流量設定節點
setLoadsImagesAutomatically(真); //支援自動加載圖檔
setDefaultTextEncodingName(“UTF-8”); //設定編碼格式
setPluginState(PluginState.OFF); //設定是否支援閃存插件
setDefaultFontSize(20); //設定預設字型大小
           

2.2WebViewClient

  • 處理各種請求通知事件
  • 應該覆寫UrlLoading(WebView視圖,字元串url)//在網頁上的所有加載都經過這個方法,這個函數我們可以做很多操作。比如擷取url,檢視url.contains(“add”),進行添加操作
//應該覆寫UrlLoading(WebView視圖,字元串url)//在網頁上的所有加載都經過這個方法,這個函數我們可以做很多操作。比如擷取url,檢視url.contains(“add”),進行添加操作

shouldOverrideKeyEvent(WebView視圖,KeyEvent事件)//處理在浏覽器中的按鍵事件。

onPageStarted(WebView視圖,字元串url,位圖圖示)/ /開始載入頁面調用,我們可以設定一個加載的頁面,告訴使用者程式在等待網絡響應。

onPageFinished(WebView視圖,String url)//在頁面加載結束時調用,我們可以關閉加載條,切換程式動作。

onLoadResource(WebView視圖,String url)//在加載頁面資源時會調用,每一個資源(比如圖檔)的加載都會調用一次。

onReceivedError(WebView視圖,int錯誤碼,字元串描述,String failingUrl)//報告錯誤資訊

doUpdateVisitedHistory(WebView視圖,String url,布爾isReload)//更新曆史記錄

onFormResubmission(WebView視圖,Message dontResend,Message重發)//應用程式重新請求網頁資料

onReceivedHttpAuthRequest(WebView視圖,HttpAuthHandler處理函數,String主機,String領域//擷取傳回資訊授權請求

onReceivedSslError(WebView視圖,SslErrorHandler處理程式,SslError錯誤)//讓webview處理https請求。

onScaleChanged(WebView視圖,float oldScale,float newScale)// WebView發生改變時調用

onUnhandledKeyEvent(WebView視圖,KeyEvent事件)// Key事件未被加載時調用
           

2.3WebChromeClient

  • 幫助webview處理js對話框,網址圖示,網址标題,網址進度
  • public void onProgressChanged(WebView view,int newProgress); //獲得網頁的加載進度,顯示在右上角的的TextView控件中
  • 公共無效onReceivedTitle(WebView視圖,字元串标題); //擷取網頁中的标題使用者設定自己界面中的标題,當加載出錯的時候,比如無網絡,這時onReceiveTitle中擷取的标題為“找不到該網頁”
  • public void onReceivedIcon(WebView視圖,位圖圖示); //擷取的Web頁中的圖示
  • 公共布爾onCreateWindow(WebView視圖,布爾isDialog,布爾isUserGesture,消息resultMsg);
  • public void onCloseWindow(WebView window);
  • 公共布爾onJsAlert(WebView視圖,字元串url,字元串消息,JsResult結果); //處理警告彈出框,html彈框的一種方式
  • public boolean onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result)//處理确認彈出框
  • public boolean onJsConfirm(WebView視圖,String url,String消息,JsResult結果); //處理提示彈出框

3.WebView頁面導航

3.1頁面跳轉

  • 設定WebViewClient,如果要跳轉不同連結,需要自定義WebViewClient,重寫shouldOverrideUrlLoading()

3.2頁面回退

  • 重寫onKeyEvent()方法

3.3頁面滑動

  • 擷取網頁高度

WebView,WebViewClient,WebChromeClient三者的差別

  • WebView:主要負責解析和渲染網頁
  • WebViewClient:輔助WebView處理各種通知 & 請求事件
  • WebChromeClient :輔助WebView處理 Javascript 的對話框,網站圖示,網站标題等等
  • 下面是小例子:
  • activity_web.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00999999"
    android:theme="@style/AppTheme"
    tools:context="com.sunny.app.itjuzi_learn.webview.controller.WebActivity">
    <include layout="@layout/layout_webview"/>
</RelativeLayout>
           
  • layout_webview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/white">

    <!-- 加載進度條 -->
    <ProgressBar
        android:id="@+id/load_progressbar"
        android:layout_width="match_parent"
        android:layout_height="3dp"
        style="@style/Widget.AppCompat.ProgressBar.Horizontal"
        android:progressDrawable="@drawable/bar_color"
        android:max="100" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:padding="5dp">

        <!-- 擷取網站的圖示 -->
        <ImageView
            android:id="@+id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <!-- 擷取網站的标題-->
        <TextView
            android:id="@+id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="16sp"
            android:textColor="@color/black"
            android:text="THIS IS WEB TITLE"/>
    </LinearLayout>

    <!--<LinearLayout-->
        <!--android:layout_width="match_parent"-->
        <!--android:layout_height="wrap_content"-->
        <!--android:orientation="horizontal"-->
        <!--android:gravity="right">-->

        <!--&lt;!&ndash;開始加載提示&ndash;&gt;-->
        <!--<TextView-->
            <!--android:id="@+id/beginloading_txt"-->
            <!--android:layout_width="wrap_content"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:textSize="12sp"-->
            <!--android:textColor="@color/com_claim_txt"-->
            <!--android:text=""/>-->

        <!--&lt;!&ndash;擷取加載進度&ndash;&gt;-->
        <!--<TextView-->
            <!--android:id="@+id/loading_txt"-->
            <!--android:layout_width="match_parent"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:textSize="12sp"-->
            <!--android:textColor="@color/grey"-->
            <!--android:text=""/>-->

        <!--&lt;!&ndash;結束加載提示&ndash;&gt;-->
        <!--<TextView-->
            <!--android:id="@+id/endloading_txt"-->
            <!--android:layout_width="wrap_content"-->
            <!--android:layout_height="wrap_content"-->
            <!--android:textSize="12sp"-->
            <!--android:textColor="@color/com_claim_txt"-->
            <!--android:text=""/>-->

    <!--</LinearLayout>-->

    <!--顯示網頁區域-->
    <WebView
        android:id="@+id/show_webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="1dp"
        />

</LinearLayout>
           
  • WebActivity.class
package com.sunny.app.itjuzi_learn.webview.controller;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.net.http.SslError;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.sunny.app.itjuzi_learn.R;
import com.sunny.app.itjuzi_learn.url.Consts;

/**
 * webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); 意思是:關閉webview中緩存
 */
public class WebActivity extends AppCompatActivity {
    //    private static final String APP_CACHE_DIRNAME = "/cache";
    private WebView mWebView;
    private WebSettings mWebSettings;
    private ImageView mIcon;
    private TextView mBeginLoading, mEndLoading, mLoading, mTitle;
    private ProgressBar mProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //顯示進度條
        requestWindowFeature(Window.FEATURE_PROGRESS);                  //帶進度
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);    //不帶進度
        setContentView(R.layout.activity_web);
        mIcon = findViewById(R.id.icon);
        mTitle = findViewById(R.id.showTitle);
//        mBeginLoading = findViewById(R.id.beginloading_txt);
//        mLoading = findViewById(R.id.loading_txt);
//        mEndLoading = findViewById(R.id.endloading_txt);
        mWebView = findViewById(R.id.show_webView);
        mProgressBar = findViewById(R.id.load_progressbar);

        mWebSettings = mWebView.getSettings();

//        設定緩存行為
//        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);   //優先使用緩存(隻要本地有,無論是否過期,或者no-cache,都使用緩存中的資料。)
//        mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);   //不使用網絡,隻從本地緩存資料中讀取
//        mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //(預設)根據cache-controller決定是否從網上加載資料
//        mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); //不使用緩存
//        結合使用(離線加載)
//        if (NetStatusUtil.isConnected(getApplicationContext())) {
//            mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根據cache-control決定是否從網絡上取資料。
//        } else {
//            mWebSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網,則從本地擷取,即離線加載
//        }
//
//        設定緩存路徑(路徑:data/data/包名)
//        String cacheDirPath = getCacheDir().getAbsolutePath() + APP_CACHE_DIRNAME;
//        mWebSettings.setAppCachePath(cacheDirPath); //設定 Application Cache 目錄

        //關閉webview中緩存
//        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);


        //websetting配置
        mWebSettings.setJavaScriptEnabled(true);                        //設定該屬性支援與js互動
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);    //支援通過JS打開新視窗

        //支援插件
//        mWebSettings.setPluginState(WebSettings.PluginState.ON); //适用于8<api<19,api=19時被棄用
//        mWebSettings.setPluginEnable(true);   //适用于api<8(當api>18時可能被隐藏或删除,編譯時會報錯)

        mWebSettings.setDomStorageEnabled(true); //開啟 DOM storage API 功能
        mWebSettings.setDatabaseEnabled(true); //開啟 database API 功能
//        mWebSettings.setAppCacheEnabled(true); //開啟 Application cache 功能

//        //設定自适應螢幕,兩者合用
        mWebSettings.setUseWideViewPort(true); //将圖檔調整到适合webview的大小
        mWebSettings.setLoadWithOverviewMode(true); // 縮放至螢幕的大小
//
縮放操作
        mWebSettings.setSupportZoom(true); //支援縮放,預設為true。是下面那個的前提。
        mWebSettings.setBuiltInZoomControls(true); //設定内置的縮放控件。若為false,則該WebView不可縮放
//        webSettings.setDisplayZoomControls(false); //隐藏原生的縮放控件
//
其他細節操作
        mWebSettings.setAllowFileAccess(true); //設定可以通路檔案
        mWebSettings.setLoadsImagesAutomatically(true); //支援自動加載圖檔
        mWebSettings.setDefaultTextEncodingName("utf-8");//設定編碼格式

        //防止webView記憶體洩露(不在XML中定義webview,在Activity中需要時定義)
//        LinearLayout linearLayout = new LinearLayout(this);
//        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
//        mWebView = new WebView(getApplicationContext());
//        mWebView.setLayoutParams(params);
//        linearLayout.addView(mWebView);

        //cookei一定設定在loadUrl()之前


        mWebView.loadUrl(Consts.WEB_URL_VIP);

        //設定不用系統浏覽器打開,直接顯示在目前WebView中(隻有沒有setWebViewClient的時候才會調用系統的浏覽器加載頁面,而并不是重寫WebViewClient的shouldOverrideUrlLoading()方法)?
        //設定webviewClient類
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //網頁版支付寶支付時需打開用戶端支付,這時會有一個appliyid會攜帶支付資訊,此時截斷不使用view加載資料,而使用intent打開手機用戶端(http://blog.csdn.net/chendong_/article/details/75152321)
                //如果不使用intent加載資料就走原來
//                if (!shouldOverrideIntentUrl(getContext(), url)) {
                    view.loadUrl(url, Api.makeHttpHeaders(getContext())); intent
//                }


                //由于WebView隻能處理http,https開頭的網頁,就會導緻其餘網頁打不開,需對其進行轉化
                try {
                    if (url == null) return false;
                    if (url.startsWith("http:") || url.startsWith("https:")) {
                        view.loadUrl(url); //view加載資料
                        return true;
                    } else {
                        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        startActivity(intent);
                        return true;
                    }
                } catch (Exception e) {
                    return false;
                }
                //傳回值為true利用WebView打開,為false調用系統或第三方浏覽器打開
//                return true;
            }

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
//                super.onPageStarted(view, url, favicon);
//                mBeginLoading.setText("開始加載了");
                Log.d("WebActivity", "開始加載了");
            }

            //加載結束
            @Override
            public void onPageFinished(WebView view, String url) {
//                super.onPageFinished(view, url);
//                mEndLoading.setText("加載完成");
                Log.d("WebActivity", "加載完成了");
            }

            //加載頁面資源時會調用,每加載一個資源(比如圖檔)調用一次
            @Override
            public void onLoadResource(WebView view, String url) {
//                super.onLoadResource(view, url);
//                設定加載資源的操作

            }


            /**
             * WebView如何加載本地頁面(加載頁面出現404時,需要給使用者展示一個相對美觀本地的頁面)
             * 步驟:
             * 1:寫一個html檔案(error_handle.html),用于出錯時展示給使用者看的提示頁面
             * 2:将該html檔案放置到代碼根目錄的assets檔案夾下
             * 3:複寫WebViewClient的onRecievedError方法
             * @param view
             * @param errorCode
             * @param description
             * @param failingUrl
             */
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//                switch (errorCode) {
//                    case HttpStatus.SC_NOT_FOUND:
//                        view.loadUrl("file:///android_assets/error_handle.html");
//                        break;
//                }
                Log.d("WebActivityError", errorCode + ",\n" + description + ",\n" + failingUrl);
            }

            /**
             * @param request
             * @param error
             */
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
//                super.onReceivedError(view, request, error);
                Log.d("WebActivity", error + "");
            }

            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                Log.d("WebActivity:", errorResponse + "");

            }


            /**
             * 處理Https請求:webView預設不處理Https請求的,頁面顯示空白,需要進行如下處理
             * @param view
             * @param handler
             * @param error
             */
            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                handler.proceed();      //等待證書響應
//                handler.cancel();       //表示挂起連接配接,為預設方式
//                handler.handleMessage(null);    //做其他處理
            }
        });

        mWebView.setWebChromeClient(new WebChromeClient() {
            //擷取網站标題
            @Override
            public void onReceivedTitle(WebView view, String title) {
//                super.onReceivedTitle(view, title);
//                mTitle.setText(title);
                Log.d("WebActivity", "标題為:" + mTitle + "," + title);
            }

            //擷取網站圖示
            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                mIcon.setImageBitmap(icon);
                Log.d("WebActivity", "網頁圖示:" + icon.toString());
            }

            //擷取加載進度
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
//                super.onProgressChanged(view, newProgress);

                if (newProgress == 100) {
                    mProgressBar.setVisibility(View.GONE);
                } else {
                    mProgressBar.setVisibility(View.VISIBLE);
                    mProgressBar.setProgress(newProgress);  //設定進度值
                }
//                if (newProgress < 100) {
//                    String progress = newProgress + " % ";
//                    mLoading.setText(progress);
//                } else if (newProgress == 100) {
//                    String progress = newProgress + "%";
//                    mLoading.setText(progress);
//                }
//                Log.d("WebActivity", "加載進度為:" + newProgress);
            }
        });


    }

    /**
     * 使用intent攔截url打開應用(支付寶)???
     * 目的:換起某些應用内部暴露的APP頁面
     */
//    private static final String ALIPAY_SCHEME = "alipays";
//
//    public static boolean shouldOverrideIntentUrl(AccessControlContext context, String url) {
//        Uri uri = Uri.parse(url);
//        if (uri != null
//                && uri.getScheme() != null
//                && uri.getScheme().equals(ALIPAY_SCHEME)) {
//            try {
//                Intent intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
//                intent.addCategory(Intent.CATEGORY_BROWSABLE);
//                intent.setComponent(null);
//                intent.setSelector(null);
                context.startActivity(intent);    //??????
//            } catch (Exception e) {
//                e.printStackTrace();
//                if (e instanceof ActivityNotFoundException) {
                    ToastUtil.show("未檢測到支付寶用戶端");
//                }
//                return true;
//            }
//            return true;
//        }
//        return false;
//    }


    //點選傳回上一頁面而不是退出浏覽器
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && mWebView.canGoBack()) { //是否可以後退
            //webView後退網頁
            mWebView.goBack();
            //前進網頁
//            mWebView.goForward();
            return true;
        }
        return super.onKeyDown(keyCode, event);
        //點選傳回,彈出提示
//        if (keyCode == KeyEvent.KEYCODE_BACK){
//            MyToast toast =new MyToast(this);
//            toast.makeText(this,"退出",0);
//        }
//        return false;
    }

    //銷毀Activity時,webView需要加載(null),移除,銷毀,置空
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mWebView != null) {
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            //清除webview所有曆史緩存,除了目前通路記錄緩存
            mWebView.clearHistory();

            //這個api僅僅清除自動完成填充的表單資料,并不會清除webview緩存到本地的資料
            mWebView.clearFormData();
            //全局的核心緩存,清除的是整個整個應用程式緩存
            mWebView.clearCache(true);
            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        } else {
            Log.d("WebActivity", "WebView為null'");
        }
    }
}

           

4.WebView緩存

在項目中如果使用到WebView控件, 當加載html頁面時, 會在/data/data/包名目錄下生成database與cache兩個檔案夾。

請求的url記錄是儲存在WebViewCache.db, 而url的内容是儲存在WebViewCache檔案夾下

4.1設定緩存

  • 控制緩存行為
//設定緩存行為
/優先使用緩存(隻要本地有,無論是否過期,或者no-cache,都使用緩存中的資料。)
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);/
mWebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);   //不使用網絡,隻從本地緩存資料中讀取
//(預設)根據cache-controller決定是否從網上加載資料
mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  
mWebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE); //不使用緩存
//結合使用(離線加載)
if (NetStatusUtil.isConnected(getApplicationContext())) {
	mWebSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根據cache-control決定是否從網絡上取資料。
} else {
	mWebSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網,則從本地擷取,即離線加載
}
//設定緩存路徑(路徑:data/data/包名)
String cacheDirPath = getCacheDir().getAbsolutePath() + APP_CACHE_DIRNAME;
 
           
  • 關閉緩存
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
           

4.2清除緩存

  • 方法
//清除webview所有曆史緩存,除了目前通路記錄緩存
mWebView.clearHistory();
//這個api僅僅清除自動完成填充的表單資料,并不會清除webview緩存到本地的資料
mWebView.clearFormData();
//全局的核心緩存,清除的是整個整個應用程式緩存
mWebView.clearCache(true);
           

5.WebCookies

  • 個人了解Cookie:
    • Cookie 是在 HTTP 協定下,伺服器或腳本可以維護客戶工作站上資訊的一種方式。
    • 由伺服器端生成浏覽器緩存的一些小量資訊,session的使用離不開它。
    • 收集整合使用者資訊,應用于使用者在不同頁面同步購物車商品。
    • 典型應用:判定使用者是否已登入網站
  • 推薦連結:http://blog.csdn.net/jdsjlzx/article/details/44630187

5.1設定Cookies

  • 更新中…
......
           

5.2清除Cookies

  • 更新中…

6.WebView通路本地資源

  • 注意:

    從網絡上下載下傳html的過程應放在工作線程中

    html下載下傳成功後渲染出html的步驟應放在UI主線程,不然WebView會報錯

    html下載下傳失敗則可以使用我們前面講述的方法來顯示自定義錯誤界面

  • 參考連結:http://blog.csdn.net/carson_ho/article/details/52693322