webview是Android里的一个很古老的组件,现在火起来一些融合开发的框架如weex、react native,flutter等,然后就会想:webview还需要继续学习吗?还会有项目继续使用吗?答案是:webview永远不会被淘汰。对是永远,因为即使使用weex等框架还是有webview组件,因为webview是加载web页面很方便的组件,所以我们学习它,优化它再迟再深入都不过分。本篇文章旨在介绍官方webview组件的基础特性以及存在的问题,力求全面,基础,后续扩展优化会另开一片文章。
webview是sdk封装的一款内核浏览器,在4.4版本之前,Android WebView基于WebKit实现。不过,在4.4版本之后,Android WebView就换成基于Chromium的实现了。基于Chromium实现,使得WebView可以更快更流畅地显示网页。
webview使用时会涉及到几个类,分别为 webview对象、webviewSetting、WebViewClient、WebChromeClient、CookieManager(CookieSyncManager)。
WebView的继承关系如下:
可见WebView是一个UI控件,用来展示内容的容器。
建议先打开源码大致看一下,看一下提供了哪些属性和枚举值,就可以大致了解可以操作的内容了。
先来看一下主要提供了哪些设置:
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);//渲染优先级,默认普通
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setAppCacheEnabled(true);
webSettings.setBlockNetworkImage(false);//网络图片资源加载关闭
webSettings.setAppCachePath("");
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//缓存模式
webSettings.setDefaultFontSize(10);
/**
* MIXED_CONTENT_ALWAYS_ALLOW:允许从任何来源加载内容,即使起源是不安全的;
* MIXED_CONTENT_NEVER_ALLOW:不允许Https加载Http的内容,即不允许从安全的起源去加载一个不安全的资源;
* MIXED_CONTENT_COMPATIBILITY_MODE:当涉及到混合式内容时,WebView 会尝试去兼容最新Web浏览器的风格。
* (5.0以下默认允许加载http和https混合的页面,5.0+默认禁止)
**/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
webViewClient是对loadUrl加载过程的监听,主要重写方法如下:
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();//允许加载https资源
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return super.shouldOverrideUrlLoading(view, request);
}
});
这个类的作用主要提供加载过程的展示包括进度、弹框等
webView.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);//加载进度
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);//页面标题
}
});
Cookie管理的兼容方案是:在sdk21以下使用CookieSyncManager,否则使用CookieManager。不论使用哪一种方式,其最终的底层实现都离不开对数据库的读写操作,而区别在于实现的策略不同罢了。
什么是cookie:最简单理解就是由http衍生出来的一种特殊的浏览器的缓存,特点是具有时效性、账户相关性、存储在客户端等。
作用:作为客户端的用户认证的通行证,比如服务端可以通过cookie来区分到底是哪个用户。
Android中Cookie的管理相关:说到cookie的管理,其实本质上就是数据的存储问题。在早期的cookie是由CookieSyncManager进行管理的,但是在sdk21之后CookieSyncManager被抛弃了,换成了CookieManager来进行管理。
Android中Cookie的存储:目前Android系统WebView是将cookie存储data/data/package_name/app_webview这个目录下的一个叫Cookies的数据中.
使用CookieSyncManager同步cookie数据:在早期手机硬件性能比较尴尬的时候,为了提升浏览器的性能,加快cookie的读写,浏览器的cookie是存储在手机的内存上的。但是,当当存储在内存上是不够的,还需要保存到存储器上,这时CookieSyncManager应运而生。借助于CookieSyncManager在内存和存储器之间同步浏览器的cookie。另外CookieSyncManager同步策略是在一个独立的线程里定时进行同步。
cookie开始同步:注意每次同步的时间间隔是5分钟
//推荐在Activity.onResume()里调用
CookieSyncManager.createInstance(context);
CookieSyncManager.getInstance().startSync();
cookie停止同步:
//Activity.onPause()里调用
CookieSyncManager.getInstance().stopSync()
cookie立即同步:调用了该方法会立即进行cookie的同步,代码如下:
//一般是在webview中的onPageFinished(WebView, String)方法进行强制同步
CookieSyncManager.getInstance().sync()
删除cookie操作:
//通常删除cookie的是这样写的
CookieSyncManager.createInstance(this);
CookieManager.getInstance().removeAllCookie();
CookieManager.getInstance().removeSessionCookie();
CookieSyncManager.getInstance().sync();
CookieSyncManager.getInstance().startSync();
从sdk21之后,webview已经内置了cookie的同步操作了。虽然不再需要关注cookie的同步,但是依然需要掌握删除cookie的操作。
删除cookie操作:底层实现是异步清除数据库的记录
CookieManager.getInstance().removeAllCookies(null);
CookieManager.getInstance().flush();
立即同步:注意到这个flush()方法就是立即同步cookie的操作,与CookieSyncManager中的sync()方法是一样的,其实查看CookieSyncManager的源码就会很清除了
@Deprecated
public void sync() {
CookieManager.getInstance().flush();
}
听说过webview的朋友肯定都知道其存在的明显的问题:
由于是基础篇,这里只做全面列举,不做展开。
造成体验差的主要原因有以下几点:
webview组件占用内存较大,容易造成内存溢出。