Android X5WebView网络监听替换WebView失败页面稳定

一.我这边是集成了腾讯所提供的X5Webview插件,没有别的原因,就感觉比原生处理的稍微好点吧。

x5Webview与H5的交互问题
x5同步cookie问题
WebView加载进度条问题处理
H5调用Android摄像头进行录制视频、H5调用Android相机进行拍照
x5WebView-WebChromeClient的方法onShowFileChooser只执行一次的问题
X5WebView的Setting需要配置那些东西
废话也不多说了,直接上代码

AndroidManifest.xml 权限

<!-- 网络权限 -->
    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- 网络状态 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--    //腾讯X5WebView权限-->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

1.MainActivity类网上也有很多案例但是处理的都不是怎么好.

package com.example.network;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;


import com.tencent.smtt.export.external.interfaces.WebResourceError;
import com.tencent.smtt.export.external.interfaces.WebResourceRequest;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Activity基类:实时获取网络状态
 * create by Travis1022 on 2021-3-25
 */
public class MainActivityextends AppCompatActivity {
    
    
    private boolean isRegistered = false;
    private IntentFilter intentFilter;
    private NetWorkChangReceiver networkChangeReceiver;
    private X5WebView webview;
    private View mErrorView;
    private RelativeLayout layout;
    private ProgressBar progressBar;
    // 页面是否加载错误
    private boolean isError = false;
    // 页面是否加载成功
    private boolean isSuccess = true;

    public class NetWorkChangReceiver extends BroadcastReceiver {
    
    

        /**
         * 获取连接类型
         *
         * @param type
         * @return
         */
        private String getConnectionType(int type) {
    
    
            String connType = "";
            if (type == ConnectivityManager.TYPE_MOBILE) {
    
    
                connType = "3G网络数据";
            } else if (type == ConnectivityManager.TYPE_WIFI) {
    
    
                connType = "WIFI网络";
            }
            return connType;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
    
    
            if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction())) {
    
    // 监听wifi的打开与关闭,与wifi的连接无关
                int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0);
                Log.e("TAG", "wifiState:" + wifiState);
                switch (wifiState) {
    
    
                    case WifiManager.WIFI_STATE_DISABLED:
                        break;
                    case WifiManager.WIFI_STATE_DISABLING:
                        break;
                }
            }
            // 监听网络连接,包括wifi和移动数据的打开和关闭,以及连接上可用的连接都会接到监听
            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
    
    
                //获取联网状态的NetworkInfo对象
                NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
                if (info != null) {
    
    

                    //如果当前的网络连接成功并且网络连接可用
                    if (NetworkInfo.State.CONNECTED == info.getState() && info.isAvailable()) {
    
    
                        if (info.getType() == ConnectivityManager.TYPE_WIFI || info.getType() == ConnectivityManager.TYPE_MOBILE) {
    
    
                            setUpView();
                            Log.i("TAG", getConnectionType(info.getType()) + "连上");
                            Toast.makeText(context, getConnectionType(info.getType()) + "连上", Toast.LENGTH_SHORT).show();
                        }
                    } else {
    
    
                        showErrorPage();

                        Log.i("TAG", getConnectionType(info.getType()) + "断开");
                        Toast.makeText(context, getConnectionType(info.getType()) + "断开", Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initHardwareAccelerate();
        webview = (X5WebView) findViewById(R.id.webview);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        //注册网络状态监听广播
        intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        networkChangeReceiver = new NetWorkChangReceiver();
        registerReceiver(networkChangeReceiver, intentFilter);
        isRegistered = true;
    }


    /**
     * 启用硬件加速
     */

    private void initHardwareAccelerate() {
    
    
        try {
    
    
            if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 11) {
    
    
                getWindow()
                        .setFlags(
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            }
        } catch (Exception e) {
    
    
        }
    }

//  数据加载
    private void setUpView() {
    
    
        if (mErrorView != null) {
    
    
            mErrorView.setVisibility(View.GONE);
        }
        webview.loadUrl("https://sports.sohu.com/");
        webview.setWebViewClient(new myWebViewClient());
        webview.setWebChromeClient(new myWebChromeClient());
        //屏幕自适应
        webview.getSettings().setJavaScriptEnabled(true);
        webview.getSettings().setUseWideViewPort(true);
        webview.getSettings().setLoadWithOverviewMode(true);
    }

    boolean mIsErrorPage;

    //  加载失败自定义
    protected void showErrorPage() {
    
    
        if (layout != null) {
    
    
            layout.setVisibility(View.VISIBLE);
        }
        if (mErrorView != null) {
    
    
            mErrorView.setVisibility(View.VISIBLE);
        }
        LinearLayout webParentView = (LinearLayout) webview.getParent();
        initErrorPage();//初始化自定义页面
        while (webParentView.getChildCount() > 1) {
    
    
            webParentView.removeViewAt(0);
        }
        @SuppressWarnings("deprecation")
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT);
        webParentView.addView(mErrorView, 0, lp);
        mIsErrorPage = true;
    }

    /**
     * WebViewClient监听
     */

    private class myWebViewClient extends WebViewClient {
    
    

        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String s) {
    
    
            webView.loadUrl(s);
            return true;
        }

        @Override
        public void onPageFinished(WebView view, String url) {
    
    
            super.onPageFinished(view, url);
            if (!isError) {
    
    
                // 在访问失败的时候会首先回调onReceivedError,然后再回调onPageFinished
                isSuccess = true;
                Log.i("网络:--", "加载成功");
            }
            // 还原变量
            isError = false;
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
    
    
            super.onReceivedError(view, errorCode, description, failingUrl);
            isError = true;
            isSuccess = false;
            showErrorPage();
            Log.i("网络:--", "加载失败");
        }
    }

    /**
     * WebChromeClient监听
     */

    private class myWebChromeClient extends WebChromeClient {
    
    

        @Override
        public void onProgressChanged(WebView webView, int i) {
    
    
            super.onProgressChanged(webView, i);
            if (i == 100) {
    
    
                progressBar.setVisibility(View.GONE);//加载完网页进度条消失
            } else {
    
    
                progressBar.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
                progressBar.setProgress(i);//设置进度值
            }
        }
    }

    /***
     * 显示加载失败时自定义的网页
     * @param post
     */
    protected void initErrorPage() {
    
    
        if (mErrorView == null) {
    
    
            mErrorView = View.inflate(this, R.layout.activity_url_error, null);
            mErrorView.setVisibility(View.VISIBLE);
            layout = (RelativeLayout) mErrorView.findViewById(R.id.online_error_btn_retry);
            layout.setVisibility(View.VISIBLE);
            layout.setOnClickListener(new View.OnClickListener() {
    
    
                public void onClick(View v) {
    
    
                    webview.reload();
                    mErrorView.setVisibility(View.GONE);
                }
            });
            mErrorView.setOnClickListener(null);
        }
    }

    /**
     * onKeyDown方法
     */

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
    
    
        if (keyCode == KeyEvent.KEYCODE_BACK) {
    
    
            if (webview != null && webview.canGoBack()) {
    
    
                webview.goBack();
                return true;
            } else {
    
    
                return super.onKeyDown(keyCode, event);
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
     * onDestroy方法
     */

    @Override
    protected void onDestroy() {
    
    
        super.onDestroy();
        if (null != webview) {
    
    
            webview.destroy();//释放资源
        }
    }
}

2.MyApplication类全局上下文类

package com.example.network;
 
import android.app.Application;
import android.util.Log;
 
import com.tencent.smtt.sdk.QbSdk;
 
public class MyApplication extends Application {
    
    
 
    @Override
    public void onCreate() {
    
    
        super.onCreate();
 
        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
    
    
 
            @Override
            public void onViewInitFinished(boolean arg0) {
    
    
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                Log.d("app", " onViewInitFinished is " + arg0);
            }
 
            @Override
            public void onCoreInitFinished() {
    
    
                // TODO Auto-generated method stub
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(),  cb);
 
    }
}

3.X5WebView类

package com.example.network;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

public class X5WebView extends WebView {
    
    
	private WebViewClient client = new WebViewClient() {
    
    
		/**
		 * 防止加载网页时调起系统浏览器
		 */
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
    
    
			view.loadUrl(url);
			return true;
		}
	};
 
	@SuppressLint("SetJavaScriptEnabled")
	public X5WebView(Context arg0, AttributeSet arg1) {
    
    
		super(arg0, arg1);
		this.setWebViewClient(client);
		// this.setWebChromeClient(chromeClient);
		// WebStorage webStorage = WebStorage.getInstance();
		initWebViewSettings();
		this.getView().setClickable(true);
	}
 
	private void initWebViewSettings() {
    
    
		WebSettings webSetting = this.getSettings();
		webSetting.setJavaScriptEnabled(true);
		webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
		webSetting.setAllowFileAccess(true);
		webSetting.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
		webSetting.setSupportZoom(true);
		webSetting.setBuiltInZoomControls(true);
		webSetting.setUseWideViewPort(true);
		webSetting.setSupportMultipleWindows(true);
		// webSetting.setLoadWithOverviewMode(true);
		webSetting.setAppCacheEnabled(true);
		// webSetting.setDatabaseEnabled(true);
		webSetting.setDomStorageEnabled(true);
		webSetting.setGeolocationEnabled(true);
		webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
		// webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
		webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
		// webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
		webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
 
		// this.getSettingsExtension().setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);//extension
		// settings 的设计
	}
 
	@Override
	protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
    
    
		boolean ret = super.drawChild(canvas, child, drawingTime);
		canvas.save();
		Paint paint = new Paint();
		paint.setColor(0x7fff0000);
		paint.setTextSize(24.f);
		paint.setAntiAlias(true);
//		if (getX5WebViewExtension() != null) {
    
    
//			canvas.drawText(this.getContext().getPackageName() + "-pid:"
//					+ android.os.Process.myPid(), 10, 50, paint);
//			canvas.drawText(
//					"X5  Core:" + QbSdk.getTbsVersion(this.getContext()), 10,
//					100, paint);
//		} else {
    
    
//			canvas.drawText(this.getContext().getPackageName() + "-pid:"
//					+ android.os.Process.myPid(), 10, 50, paint);
//			canvas.drawText("Sys Core", 10, 100, paint);
//		}
//		canvas.drawText(Build.MANUFACTURER, 10, 150, paint);
//		canvas.drawText(Build.MODEL, 10, 200, paint);
		canvas.restore();
		return ret;
	}
 
	public X5WebView(Context arg0) {
    
    
		super(arg0);
		setBackgroundColor(85621);
	}

}

4.LoadingImageView 由于我这边替换了WebView失败页面所加载的页面所以有这个

package com.example.network;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;

/**
 * 
 * @author 
 *
 */
@SuppressLint("AppCompatCustomView")
public class LoadingImageView extends ImageView {
    
    
	private AnimationDrawable mAnimationDrawable;

	public LoadingImageView(Context context, AttributeSet attrs) {
    
    
		super(context, attrs);
		setBackgroundResource(R.drawable.loading);
		mAnimationDrawable = (AnimationDrawable) getBackground();
		mAnimationDrawable.start();
	}

	@Override
	protected void onVisibilityChanged(View changedView, int visibility) {
    
    

		super.onVisibilityChanged(changedView, visibility);
		if (visibility == View.GONE) {
    
    
			mAnimationDrawable.stop();
		}
	}
}

这边附上Demo地址 提取码:54tw

猜你喜欢

转载自blog.csdn.net/weixin_42996187/article/details/115204522