WebView使用常见忽视点
1.WebView使用
1.webview:负责页面的渲染
2.WebViewClient:辅助WebView处理各种通知和请求事件
3.WebChromeClient:辅助WebView处理JavaScript中的对话框, 网址图标和标题,进度条等
细节:
如果我们想控制不同链接的跳转方式, 我们需要继承WebViewClient重写shouldOverrideUrlLoading()方法
关于shouldOverrideUrlLoading()方法的两点说明:
1 方法返回值
返回true: Android 系统会处理URL, 一般是唤起系统浏览器。
返回false: 当前 WebView 处理URL。
由于默认放回false, 如果我们只想在WebView内处理链接跳转只需要设置mWebView.setWebViewClient(new WebViewClient())即可
注意:
如果你只需要避免启动系统浏览器来加载页面的情况,只需要这么写就可以了
webView.setWebViewClient(new WebViewClient());
url存在重定向,无法回退
shouldOverrideUrlLoading(WebView view, String url)
的返回值决定了webview是否自动处理该url,也就是是否加载。当返回true时,由程序处理,当返回false时,webview会自己处理,也就是相当于自动执行了loadUrl方法。
2 方法deprecated问题
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.toString());
return true;
}
shouldOverrideUrlLoading()方法在API >= 24时被标记deprecated, 它的替代方法是
3. 页面回退
Android的返回键, 如果想要实现WebView内网页的回退, 可以重写onKeyEvent()方法。
4 页面滑动
三个判断高度的方法:
1.getScrollY():该方法返回的是当前可见区域的顶端距整个页面顶端的距离,也就是当前内容滚动的距离.
2.getHeight();
getBottom();
该方法都返回当前WebView这个容器的高度
3.getContentHeight();:
返回的是整个html的高度, 但并不等同于当前整个页面的高度, 因为WebView有缩放功能, 所以当前整个页面的高度实际上应该是原始html的高度:
if (webView.getContentHeight() * webView.getScale() == (webView.getHeight() + webView.getScrollY())) {
//已经处于底端
}
if(webView.getScrollY() == 0){
//处于顶端
}
不过从API 17开始, mWebView.getScale()被标记为deprecated
public class CustomWebView extends WebView {
public CustomWebView(Context context) {
super(context);
setWebViewClient(new WebViewClient() {
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
mCurrentScale = newScale
}
});
}
2.WebView缓存实现
当加载html页面时, 会在/data/data/包名目录下生成database与cache两个文件夹。
请求的url记录是保存在WebViewCache.db
而url的内容是保存在WebViewCache文件夹下
控制缓存行为的相关API:
WebSettings webSettings = mWebView.getSettings();
//优先使用缓存
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//只在缓存中读取
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ONLY);
/不使用缓存
WwebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
清除缓存
clearCache(true); //清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
clearHistory (); //清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.
clearFormData () //这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。
3.WebView本地资源访问
当我们在WebView中加载出从web服务器上拿取的内容时,是无法访问本地资源的,如assets目录下的图片资源,因为这样的行为属于跨域行为(Cross-Domain),而WebView是禁止
的。解决这个问题的方案是把html内容先下载到本地,然后使用loadDataWithBaseURL加载html。这样就可以在html中使用 file:///android_asset/xxx.png 的链接来引用包里
面assets下的资源了。
private void loadWithAccessLocal(final String htmlUrl) {
new Thread(new Runnable() {
public void run() {
try {
final String htmlStr = NetService.fetchHtml(htmlUrl);
if (htmlStr != null) {
TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
loadDataWithBaseURL(htmlUrl, htmlStr, "text/html", "UTF-8", "");
}
});
return;
}
} catch (Exception e) {
Log.e("Exception:" + e.getMessage());
}
TaskExecutor.runTaskOnUiThread(new Runnable() {
@Override
public void run() {
onPageLoadedError(-1, "fetch html failed");
}
});
}
}).start();
}
4.WebView loadUrl 和reload区别
loadUrl会有缓存策略,遇到带#的网页不会刷新,reload无视缓存策略会强制刷新。
但是项目里实验过 前两者都不生效,改为:webview.loadUrl(“javascript:window.location.reload(true)”);生效.具体原理待研究
5.WebView clearHistory()不生效
这个情况产生的原因是我们在loadUrl的时候,由于新的页面还没有完全加载出来,所以clearHistory没有起作用,因为要保证至少一个页面在最上边,所以上一个页面没有被移除掉。解决这个问题可以在onPageFinished方法中添加clearHistory方法,或者延时调用clearHistory方法。