预览
基础
简介
Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。
WebView的状态
//激活WebView为活跃状态,能正常执行网页的响应
webView.onResume() ;
//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
//通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。webView.onPause();//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
//它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
webView.onPause();
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
rootLayout.removeView(webView);
webView.destroy();
前进/后退
//是否可以后退
Webview.canGoBack()
//后退网页
Webview.goBack()
//是否可以前进
Webview.canGoForward()
//前进网页
Webview.goForward()
//以当前的index为起始点前进或者后退到历史记录中指定的steps
//如果steps为负数则为后退,正数则为前进
Webview.goBackOrForward(intsteps)
//常规用法
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
js和原生通信的方式和区别
特别注意: JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会被调用。
原生调JS
调用方式 | 优点 | 使用场景 |
---|---|---|
loadUrl() | 方便简洁 | 不需要获取返回值,要求比较低 |
evaluateJavascript() | 效率高 | 4.4以上可以用 |
JS调原生
调用方式 | 优点 | 使用场景 |
---|---|---|
addJavascriptInterface() | 方便简洁 | 4.2以下有漏洞,以上无问题 |
shouldOverrideUrlLoading()回调拦截url | 不存在漏洞 | iOS大多使用这种方式 |
onJsAlert、onJsConfirm、onJsPrompt | js的相关弹窗调用可以被原生拦截 | 感觉使用场景单一,基本上就是一些提示、确认的弹窗,不足以满足需求 |
WebView的漏洞类型及补救措施
任意代码执行漏洞
方式:
WebView 中 addJavascriptInterface() 接口
WebView 内置导出的 searchBoxJavaBridge_对象
WebView 内置导出的 accessibility 和 accessibilityTraversalObject 对象
解决: 规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
密码明文存储漏洞
开启后,在用户输入密码时,会弹出提示框:询问用户是否保存密码;
如果选择”是”,密码会被明文保到 /data/data/com.package.name/databases/webview.db 中,这样就有被盗取密码的危险
解决:
WebSettings.setSavePassword(false)
域控制不严格漏洞
即 A 应用可以通过 B 应用导出的 Activity 让 B 应用加载一个恶意的 file 协议的 url,从而可以获取 B 应用的内部私有文件,从而带来数据泄露威胁
解决:
// 需要使用 file 协议
setAllowFileAccess(true);
setAllowFileAccessFromFileURLs(false);
setAllowUniversalAccessFromFileURLs(false); // 禁止 file 协议加载 JavaScript
if (url.startsWith(“file://”) {
setJavaScriptEnabled(false);
} else {
setJavaScriptEnabled(true);
}
性能优化汇总
一个加载网页的过程中,native、网络、后端处理、CPU都会参与,各自都有必要的工作和依赖关系,让他们相互并行处理而不是相互阻塞才可以让网页加载更快:
- WebView初始化慢,可以在初始化同时先请求数据,让后端和网络不要闲着。
- 脚本执行慢,就让脚本在最后运行,不阻塞页面解析,或者可以把框架代码拆分出来,在请求页面之前就执行好。
- 同时,合理的预加载、预缓存可以让加载速度的瓶颈更小。
- WebView初始化慢,就随时初始化好一个WebView待用。
- DNS和链接慢,想办法复用客户端使用的域名和链接。