1、webView的状态
onResume:激活webview为活跃状态,能正常执行网页响应。
onPasue:当页面失去焦点或者不可见状态,执行该方法,表示通知内核暂停所有动作。
pauseTimers,当前应用程序被切换到后台的时候,该方法会通知全局应用程序的webView暂停所有绘制,解析等动作,降低CPU功耗
resumeTimers
退出释放
private void releaseWebView() {
if (freedomWebView != null) {
freedomWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
((ViewGroup) freedomWebView.getParent()).removeView(freedomWebView);
freedomWebView.destroy();
freedomWebView = null;
}
}
2、前进与后退
webview.canGoBack 是否可以后退
webview.goBack 后退
webview.canGoForward 是否可以前进
webview.goForward 前进
webview.goBackOrForward(steps),以当前页面为基准,前进或者后退steps个页面。负数前进,负数后退
3、清理缓存
//清除网页访问留下的缓存
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
Webview.clearCache(true);
//清除当前webview访问的历史记录
//只会webview访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory();
//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
Webview.clearFormData();
4、缓存模式
//LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
//LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
//LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据。
5、http与https混合加载模式
MIXED_CONTENT_NEVER_ALLOW:Webview不允许一个安全的站点(https)去加载非安全的站点内容(http),比如,https网页内容的图片是http链接。强烈建议App使用这种模式,因为这样更安全。
MIXED_CONTENT_ALWAYS_ALLOW:在这种模式下,WebView是可以在一个安全的站点(Https)里加载非安全的站点内容(Http),这是WebView最不安全的操作模式,尽可能地不要使用这种模式。
MIXED_CONTENT_COMPATIBILITY_MODE:在这种模式下,当涉及到混合式内容时,WebView会尝试去兼容最新Web浏览器的风格。一些不安全的内容(Http)能被加载到一个安全的站点上(Https),
而其他类型的内容将会被阻塞。这些内容的类型是被允许加载还是被阻塞可能会随着版本的不同而改变,并没有明确的定义。这种模式主要用于在App里面不能控制内容的渲染,但是又希望在一个安全的环境下运行。
6、webview与原生native的交互
对于Android调用JS代码的方法有2种:
通过WebView的loadUrl() mWebView.loadUrl("javascript:callJS()"); 该方法会使得页面刷新
通过WebView的evaluateJavascript() 该方法不会使页面刷新,但要求4.4以上,并且有返回值
mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//此处为 js 返回的结果
}
});
对于JS调用Android代码的方法有3种:
通过WebView的addJavascriptInterface()进行对象映射
通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url,双方定义好相关协议
通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()消息,参考webChromeClient.
在这些回调方法中一定要对JsResult result对象执行confirm或者cancel方法来释放js资源,不然会出现卡死
public class AndroidtoJs {
// 定义JS需要调用的方法
// 被JS调用的方法必须加入@JavascriptInterface注解
@JavascriptInterface
public void hello(String msg) {
System.out.println("JS调用了Android的hello方法");
}
}
mWebView.addJavascriptInterface(new AndroidtoJs(), "free");//AndroidtoJS类对象映射到js的free对象
function callAndroid(){
// 由于对象映射,所以调用free对象等于调用Android映射的对象
free.hello("js调用了android中的hello方法");
}
7、webview漏洞处理
1、开启addJavascriptInterface()会出现当JS拿到Android这个对象后,就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行
解决方案:在4.4以上,需要在方法上加上注解 @JavascriptInterface
2、密码明文存储漏洞,mWebView.setSavePassword(true)默认是打开的,这样子密码会明文存储
解决方案:WebSettings.setSavePassword(false)
3、setAllowFileAccess()设置是否允许 WebView 使用 File 协议,最好根据webView加载的内容来判断是否开启。如果为false,则不能加载本地html
setAllowFileAccessFromFileURLs()设置是否允许通过 file url 加载的 Js代码读取其他的本地文件,最好根据webView加载的内容来判断是否开启。
setAllowUniversalAccessFromFileURLs()设置是否允许通过 file url 加载的 Javascript 可以访问其他的源(包括http、https等源),最好根据webView加载的内容来判断是否开启。
8、缓存预加载机制
webView自身缓存机制
浏览器 缓存机制:根据 HTTP 协议头里的 Cache-Control(或 Expires)和 Last-Modified(或 Etag)等字段来控制文件缓存的机制,参考http缓存机制
Application Cache 缓存机制,它是对浏览器缓存机制的补充
// 通过设置WebView的settings来实现
WebSettings settings = getSettings();
String cacheDirPath = context.getFilesDir().getAbsolutePath()+"cache/";
// 1. 设置缓存路径
settings.setAppCachePath(cacheDirPath);
// 2. 设置缓存大小
settings.setAppCacheMaxSize(20*1024*1024);
// 3. 开启Application Cache存储机制
settings.setAppCacheEnabled(true);
// 特别注意
// 每个 Application 只调用一次 WebSettings.setAppCachePath() 和
WebSettings.setAppCacheMaxSize()
Dom Storage 缓存机制:通过webSetting开启,通过存储字符串的 Key - Value 对来提供,类似Android 的 SharedPreference机制
Web SQL Database 缓存机制:基于 SQL 的数据库存储机制,官方推荐不在使用。
Indexed Database 缓存机制:属于 NoSQL 数据库,通过存储字符串的 Key - Value 对来提供,settings.setJavaScriptEnabled(true);
只需设置支持JS就自动打开IndexedDB存储机制
自己构建webView缓存
H5页面有一些更新频率低、常用 & 固定的静态资源文件(如JS、CSS文件、图片等),这些文件的加载,不用通过服务器获取,直接用本地的即可。
解决方案:通过拦截H5页面的资源网络请求 从而 直接从本地读取资源 而不需要发送网络请求到服务器读取。重写shouldInterceptRequest
步骤: 事先将更新频率较低、常用 & 固定的H5静态资源 文件(如JS、CSS文件、图片等) 放到本地
拦截H5页面的资源网络请求 并进行检测
如果检测到本地具有相同的静态资源 就 直接从本地读取进行替换 而 不发送该资源的网络请求 到 服务器获取
或者直接套用本地模板,采用loadDataWithBaseURL方法加载
WebViewClient中方法执行顺序
onPageStarted
shouldInterceptRequest 多次执行,每次加载资源前调用,可以进行拦截
onLoadResource 多次执行,开始加载资源
onPageFinished