public class X5WebView extends WebView {
public X5WebView(Context arg0) {
this(arg0,null);
}
public X5WebView(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
setBackgroundColor(85621);
if (!isInEditMode()) {
initView(arg0);
}
initWebViewSettings();
this.getView().setClickable(true);
this.getView().setOverScrollMode(View.OVER_SCROLL_ALWAYS);
}
private void initView(Context context) {
LogUtils.i(getX5WebViewExtension() == null ? "Sys Core" : "X5 Core:" + QbSdk.getTbsVersion(getContext()));
}
private void initWebViewSettings() {
WebSettings webSettings = this.getSettings();
webSettings.setAllowFileAccess(true);
webSettings.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
webSettings.setUseWideViewPort(true);
webSettings.setSupportMultipleWindows(false);
webSettings.setLoadWithOverviewMode(true);
webSettings.setAppCacheEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setAppCacheMaxSize(Long.MAX_VALUE);
webSettings.setAppCachePath(this.getContext().getDir("appcache", 0).getPath());
webSettings.setDatabasePath(this.getContext().getDir("databases", 0).getPath());
webSettings.setGeolocationDatabasePath(this.getContext().getDir("geolocation", 0)
.getPath());
webSettings.setPluginState(WebSettings.PluginState.ON_DEMAND);
//this.getSettingsExtension().setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);//extension// settings 的设计
}
}
activity中使用:
private boolean clear;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//mViewParent 为 FrameLayout,动态添加WebView到FrameLayout中
mWebView = WebViewPool.getInstance().getWebView();
mViewParent.addView(mWebView, new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT));
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void doUpdateVisitedHistory(WebView webView, String s, boolean b) {
//处理历史视图问题
if (clear){
webView.clearHistory();
clear = false;
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
WebViewPool.getInstance().recycleWebView(mViewParent,mWebView);
mWebView = null;
/* if (mWebView != null) {
mWebView.release();
}*/
}
package com.sjl.bookmark.util;
import android.view.ViewGroup;
import com.sjl.bookmark.app.MyApplication;
import com.sjl.bookmark.widget.X5WebView;
import java.util.ArrayList;
import java.util.List;
public class WebViewPool {
private static List<WebVieWrap> webViewPool = new ArrayList<>();
private static int maxSize = 2;
private WebViewPool() {
webViewPool = new ArrayList<>();
}
private static volatile WebViewPool instance = null;
public static WebViewPool getInstance() {
if (instance == null) {
synchronized (WebViewPool.class) {
if (instance == null) {
instance = new WebViewPool();
}
}
}
return instance;
}
/**
* webView 初始化
* 最好放在application onCreate里
*/
public static void init() {
for (int i = 0; i < maxSize; i++) {
X5WebView webView = new X5WebView(MyApplication.getContext());
WebVieWrap webVieWrap = new WebVieWrap();
webVieWrap.x5WebView = webView;
webViewPool.add(webVieWrap);
}
}
/**
* 获取webView
*/
public synchronized X5WebView getWebView() {
if (webViewPool.size() < maxSize) {
return buildWebView();
}
X5WebView x5WebView = checkWebView();
if (x5WebView != null) {
return x5WebView;
}
//再次判断
if (webViewPool.size() < maxSize) {
return buildWebView();
}
try {
wait(2 * 1000);
x5WebView = getWebView();
return x5WebView;
} catch (Exception e) {
}
throw new RuntimeException("webView池已满");
}
private X5WebView checkWebView() {
for (int i = webViewPool.size() - 1; i >= 0; i--) {
WebVieWrap webVieWrap = webViewPool.get(i);
if (webVieWrap.inUse) {
continue;
}
X5WebView x5WebView = webVieWrap.x5WebView;
webVieWrap.inUse = true;
return x5WebView;
}
return null;
}
/**
* 回收webView
* @param webView
*/
public synchronized void recycleWebView(X5WebView webView) {
for (int i = 0; i < webViewPool.size(); i++) {
WebVieWrap webVieWrap = webViewPool.get(i);
X5WebView temp = webVieWrap.x5WebView;
if (webView == temp) {
temp.stopLoading();
temp.setWebChromeClient(null);
temp.setWebViewClient(null);
temp.clearHistory();
// temp.clearCache(true);
temp.loadUrl("about:blank");
temp.pauseTimers();
webVieWrap.inUse = false;
break;
}
}
notifyAll();
}
/**
* 创建webView
* @return
*/
private X5WebView buildWebView() {
X5WebView webView = new X5WebView(MyApplication.getContext());
WebVieWrap webVieWrap = new WebVieWrap();
webVieWrap.x5WebView = webView;
webViewPool.add(webVieWrap);
return webView;
}
/**
* 销毁连接池
*/
public static void destroyPool() {
try {
if (webViewPool.size() == 0) {
return;
}
for (WebVieWrap webVieWrap : webViewPool) {
X5WebView webView = webVieWrap.x5WebView;
webView.destroy();
}
webViewPool.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 回收webView ,解绑
*
* @param webView 需要被回收的webView
*/
public void recycleWebView(ViewGroup view, X5WebView webView) {
if (view != null && webView != null){
recycleWebView(webView);
view.removeView(webView);
}
}
/**
* 设置webView池个数
*
* @param size webView池个数
*/
public void setMaxPoolSize(int size) {
maxSize = size;
}
public static class WebVieWrap {
public X5WebView x5WebView;
public boolean inUse;
}
}
WebView 动态的加载、销毁,在application中初始化new
独立进程,与主进程分开,使用全局上下文,避免影响主线程和oom
WebView复用池
DNS解析优化(接口与网页主域名一致)
离线预推,下发离线包,并增量更新
网页按节点局部刷新
自定义实现图片资源缓存
加载本地网页
加载缓慢,加载过程包括网页中自带的url等图片什么的资源耗费时间
参考(怕下次找不到所以搬过来):Android WebView最佳优化(WebView池)_此非梦亦非幻的博客-CSDN博客_android webview优化