WebViewPool,当重新使用 WebViewPool 中的 WebView 时,最后 html 页显示在新 url 之前
WebViewPool, Last html page show before new url when reuse WebView from WebViewPool
有一个WebViewPool,当Activity/Fragment被销毁时,webview将被重置并添加到WebViewPool。
以下是WebViewPool的代码:
public class WebViewPool {
private static volatile WebViewPool sINSTANCE;
private int mMaxSize;
private List<WebView> mAvailableList;
private List<WebView> mInUsedList;
private IWebViewPoolFactory mFactory;
private WebViewPool() {
}
public static WebViewPool getInstance() {
if (sINSTANCE == null) {
synchronized (WebViewPool.class) {
if (sINSTANCE == null) {
sINSTANCE = new WebViewPool();
}
}
}
return sINSTANCE;
}
public void init(IWebViewPoolFactory factory,boolean lazy) {
init(2, factory,lazy);
}
public void init(int maxSize, IWebViewPoolFactory factory,boolean lazy) {
mMaxSize = maxSize;
mFactory = factory;
mAvailableList = new ArrayList<>(maxSize);
mInUsedList = new ArrayList<>(maxSize);
if (!lazy) {
create();
}
}
private synchronized void create() {
if (mFactory == null) {
return;
}
for (int i = 0; i < mMaxSize; i++) {
WebView webView = mFactory.create(new MutableContextWrapper(APP.getApplicationContext()));
mAvailableList.add(webView);
}
}
/**
* get webview form pool
* @param context
* @return
*/
public synchronized WebView getWebView(Context context) {
if(!(context instanceof Activity)){
throw new IllegalStateException("Context must be Activity");
}
WebView webView = null;
if (mAvailableList.size() > 0) {
webView = mAvailableList.remove(0);
} else {
if (mFactory != null) {
webView = mFactory.create(new MutableContextWrapper(APP.getApplicationContext()));
}
}
if (webView != null) {
((MutableContextWrapper) webView.getContext()).setBaseContext(context);
mInUsedList.add(webView);
}
return webView;
}
/**
* reset/destroy webview when activity/fragemnt is destroyed
* @param webView
*/
public synchronized void restWebView(WebView webView) {
if (webView == null || mFactory == null) {
return;
}
mFactory.reset(webView);
((MutableContextWrapper) webView.getContext()).setBaseContext(APP.getApplicationContext());
if (mInUsedList.contains(webView)) {
mInUsedList.remove(webView);
if (mAvailableList.size() < mMaxSize) {
mAvailableList.add(webView);
} else {
mFactory.destroy(webView);
}
} else {
mFactory.destroy(webView);
}
}
}
以下是reset
函数的部分代码:
public void reset(WebView webView) {
if(webView==null){
return;
}
ViewParent viewParent = webView.getParent();
if (viewParent!=null) {
((ViewGroup)viewParent).removeView(webView);
}
webView.stopLoading();
webView.clearCache(false);
webView.loadUrl("about:blank");
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
webView.clearHistory();
}
}, 1000);
}
但是当重新使用 webview 时,最后一个 html 页面先显示在新 url sometimes.It 之前并不是每次都会发生。我搜索了 Google,但没有搜索 work.Does 有人知道原因吗?谢谢!
这个问题终于解决了!原因是在未加载 about:blank
时将重置的 WebView 添加到可用列表,因此 clearHistory()
不起作用。
因此,当 activity/fragment 被销毁时,重置 webview 但不添加到可用列表,当 url 为 about:blank
时在 onPageFinished()
调用 clearHistory()
:
@Override
public void onPageFinish(String url, boolean success) {
if("about:blank".equals(url)){
webView.clearHistory();
//then add the webview to available list;
}
}
有一个WebViewPool,当Activity/Fragment被销毁时,webview将被重置并添加到WebViewPool。
以下是WebViewPool的代码:
public class WebViewPool {
private static volatile WebViewPool sINSTANCE;
private int mMaxSize;
private List<WebView> mAvailableList;
private List<WebView> mInUsedList;
private IWebViewPoolFactory mFactory;
private WebViewPool() {
}
public static WebViewPool getInstance() {
if (sINSTANCE == null) {
synchronized (WebViewPool.class) {
if (sINSTANCE == null) {
sINSTANCE = new WebViewPool();
}
}
}
return sINSTANCE;
}
public void init(IWebViewPoolFactory factory,boolean lazy) {
init(2, factory,lazy);
}
public void init(int maxSize, IWebViewPoolFactory factory,boolean lazy) {
mMaxSize = maxSize;
mFactory = factory;
mAvailableList = new ArrayList<>(maxSize);
mInUsedList = new ArrayList<>(maxSize);
if (!lazy) {
create();
}
}
private synchronized void create() {
if (mFactory == null) {
return;
}
for (int i = 0; i < mMaxSize; i++) {
WebView webView = mFactory.create(new MutableContextWrapper(APP.getApplicationContext()));
mAvailableList.add(webView);
}
}
/**
* get webview form pool
* @param context
* @return
*/
public synchronized WebView getWebView(Context context) {
if(!(context instanceof Activity)){
throw new IllegalStateException("Context must be Activity");
}
WebView webView = null;
if (mAvailableList.size() > 0) {
webView = mAvailableList.remove(0);
} else {
if (mFactory != null) {
webView = mFactory.create(new MutableContextWrapper(APP.getApplicationContext()));
}
}
if (webView != null) {
((MutableContextWrapper) webView.getContext()).setBaseContext(context);
mInUsedList.add(webView);
}
return webView;
}
/**
* reset/destroy webview when activity/fragemnt is destroyed
* @param webView
*/
public synchronized void restWebView(WebView webView) {
if (webView == null || mFactory == null) {
return;
}
mFactory.reset(webView);
((MutableContextWrapper) webView.getContext()).setBaseContext(APP.getApplicationContext());
if (mInUsedList.contains(webView)) {
mInUsedList.remove(webView);
if (mAvailableList.size() < mMaxSize) {
mAvailableList.add(webView);
} else {
mFactory.destroy(webView);
}
} else {
mFactory.destroy(webView);
}
}
}
以下是reset
函数的部分代码:
public void reset(WebView webView) {
if(webView==null){
return;
}
ViewParent viewParent = webView.getParent();
if (viewParent!=null) {
((ViewGroup)viewParent).removeView(webView);
}
webView.stopLoading();
webView.clearCache(false);
webView.loadUrl("about:blank");
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
webView.clearHistory();
}
}, 1000);
}
但是当重新使用 webview 时,最后一个 html 页面先显示在新 url sometimes.It 之前并不是每次都会发生。我搜索了 Google,但没有搜索 work.Does 有人知道原因吗?谢谢!
这个问题终于解决了!原因是在未加载 about:blank
时将重置的 WebView 添加到可用列表,因此 clearHistory()
不起作用。
因此,当 activity/fragment 被销毁时,重置 webview 但不添加到可用列表,当 url 为 about:blank
时在 onPageFinished()
调用 clearHistory()
:
@Override
public void onPageFinish(String url, boolean success) {
if("about:blank".equals(url)){
webView.clearHistory();
//then add the webview to available list;
}
}