一.我这边是集成了腾讯所提供的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.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/");
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
更多推荐
Android X5WebView网络监听替换WebView失败页面稳定
发布评论