WebView中加载页面错误处理

/ Android / 没有评论 / 3108浏览

github地址(完整Demo下载,欢迎访问)

https://github.com/zhouxu88/ErroWebViewDemo

在Android项目中,我们通常会用WebView来加载网页面,当我们的手机没有联网,或是服务端不小心瘫痪的时候,WebView展示的效果就比较丑。

解决办法

我们自定义一个View用来展示加载失败的样子,或者我们也可以直接写一个错误展示的HTML让WebView加载等等。我们进行重写的方法是WebViewClient的onReceivedError()方法。

效果图

自定义加载网页错误的view.jpg

MainActivity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private WebView webView;
    private FrameLayout loadingLayout; //提示用户正在加载数据
    private RelativeLayout webParentView;
    private View mErrorView; //加载错误的视图

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = (WebView) findViewById(R.id.webView);
        loadingLayout = (FrameLayout) findViewById(R.id.loading_layout);
        initErrorPage();//初始化自定义页面
        initWebView();
    }

    private void initWebView() {
        //加载需要显示的网页
        webView.loadUrl("http://www.baidu.com/");
        WebSettings mWebSettings = webView.getSettings();
        mWebSettings.setJavaScriptEnabled(true);    //允许加载javascript
        mWebSettings.setSupportZoom(true);          //允许缩放
        mWebSettings.setBuiltInZoomControls(true);  //原网页基础上缩放
        mWebSettings.setUseWideViewPort(true);      //任意比例缩放
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                //6.0以下执行
                Log.i(TAG, "onReceivedError: ------->errorCode" + errorCode + ":" + description);
                //网络未连接
                showErrorPage();
            }

            //处理网页加载失败时
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                //6.0以上执行
                Log.i(TAG, "onReceivedError: ");
                showErrorPage();//显示错误页面
            }
        });

        webView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                Log.i(TAG, "onProgressChanged:----------->" + newProgress);
                if (newProgress == 100) {
                    loadingLayout.setVisibility(View.GONE);
                }
            }

         
            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                Log.i(TAG, "onReceivedTitle:title ------>" + title);
                if (title.contains("404")){
                    showErrorPage();
                }
            }
        });

        webParentView = (RelativeLayout) webView.getParent(); //获取父容器
    }

    /**
     * 显示自定义错误提示页面,用一个View覆盖在WebView
     */
    private void showErrorPage() {
        webParentView.removeAllViews(); //移除加载网页错误时,默认的提示信息
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        webParentView.addView(mErrorView, 0, layoutParams); //添加自定义的错误提示的View
    }

    /***
     * 显示加载失败时自定义的网页
     */
    private void initErrorPage() {
        if (mErrorView == null) {
            mErrorView = View.inflate(this, R.layout.layout_load_error, null);
        }
    }
}

activity_main.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"
    tools:context="com.zx.errowebviewdemo.MainActivity">

   <WebView
       android:id="@+id/webView"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />


   <!--加载提示的loading图-->
   <include
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       layout="@layout/loading_anim"
       android:layout_centerInParent="true"/>
</RelativeLayout>

layout_load_error.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/load_error_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <!--加载网页错误的提示图-->
    <ImageView
        android:id="@+id/error_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:contentDescription="@null"
        android:src="@mipmap/no_data" />

    <!--点击提示文字,重新加载网页-->
    <TextView
        android:id="@+id/reload_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/error_iv"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="8dp"
        android:gravity="center"
        android:text="数据获取失败\n,  请检查网络后再重试 ~~~" />
</RelativeLayout>

layout/loading_anim.xml

<?xml version="1.0" encoding="utf-8"?><!--加载提示图-->

    <FrameLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/loading_layout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:contentDescription="@null"
            android:scaleType="centerCrop"
            android:src="@drawable/beijing" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:contentDescription="@null"
            android:scaleType="centerCrop"
            android:src="@drawable/loading_anim" />

        <!--loading提示图-->
        <TextView
            android:id="@+id/loading_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_marginBottom="3dp"
            android:gravity="center"
            android:text="@string/please_wait"
            android:textColor="#ffffff" />

    </FrameLayout>