1、WebView作用与应用场景
作用:(1)显示和渲染html5页面;(2)直接使用html文件作为布局,包括网络html文件以及本地assets中html文件;(3)可以和JavaScript交互
html5与安卓原生比较
用户体验 | web App | native App |
---|---|---|
需要下载 | 即用即得 | 需要 |
应用可实现功能 | 大部分 | 全部 |
响应速度 | 一般 | 快 |
UI | 几乎可实现任意效果UI | 可实现任意效果UI |
影音功能 | 可 | 可 |
原生应用场景:用户体验、数据安全、流量转化 | ||
html5应用场景:页面风格无系统要求、交互少、点击深度比较深 |
2、WebView常用方法
加载一个网页
webView.loadUrl("https://www.google.com/")
加载assets文件夹下的html文件
webView.loadUrl("file:///android_asset/test.html")
加载手机本地的html页面
webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html")
激活webview为活跃状态,能够执行网页的响应
webView.onResume();
页面失去焦点被切换到后台不可见状态,需要执行onPause, 通知内核暂停所有的动作,包括DOM的解析,plugin的执行,JavaScript执行
webView.onPause();
当应用程序被切换到后台时,暂停应用中所有webview的layout、parsing、javacripttimer,降低CPU功能
webView.pauseTimers();
恢复pauseTimers状态
webView.resumeTimers();
销毁webview:当关闭Activity时,如果webview的音乐或视频还在播放,就必须销毁webview, 这时需要解除webview与Activity的关联,先从父容器中移除webview再销毁webview
webView.removeView(webView); webView.destroy();
是否可以后退
webView.canGoBack();
后退网页
webView.goBack();
是否可以前进
webView.canGoForward();
前进网页
webView.goForward();
以当前的index为起点前进或者后退到历史记录中指定的steps, steps为负表示后退,为正表示前进
webView.goBackOrForward(int steps);
Back控制网页后退:如果不做任何处理, 点击back键, 当前Activity会结束,可以重写Activity的onKeyDown事件,由WebView处理Back键,实现Back键控制网页后退的功能,
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
清除网页访问留下的缓存, 内核缓存时全局的,因此针对整个应用程序
webView.clearCache(true);
清除当前webview访问历史记录,保留当前访问记录
webView.clearHistory();
清除自动完成填充的表单数据,不会清除webview存储到本地的数据
webView.clearFormData();
3、WebSettings类:webview与js交互、网页缩放、网页编码格式等等
获取WebSetting类
WebSettings webSettings = webView.getSettings();
允许页面进行js交互(如果js有执行动画,需要在onStop和onResume中分别禁止和开启js交互,以减少cpu、电量等资源消耗)
webSettings.setJavaScriptEnabled(true);
支持插件
webSettings.setPluginsEnabled(true);
设置屏幕自适应
webSettings.setLoadWithOverviewMode(true); //缩放至屏幕的大小
缩放操作
webSettings.setSupportZoom(true);// 支持缩放,setBuiltInZoomControls设置为true为前提
webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件,若为false,则webview不可缩放
webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件
其他细节操作
webSettings.setCacheMode(WebSettings.Load_CACHE_ELSE_NETWORK); //关闭webview中缓存
webSettings.setAllowFileAccess(true); //设置可以访问文件
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过js打开新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
webSettings.setDefaultTextEncodingName("utf-8"); //设置编码格式
4、WebViewClient类:webview处理页面拦截、页面开始加载、页面结束加载等
重写shouldOverrideUrlLoading方法,拦截一些url等等
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
重写onPageStarted、onPageFinished方法,显示或者结束进度条等等
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//加载开始的操作
}
@Override
public void onPageFinished(WebView view, String url) {
//结束后的操作
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//页面加载错误后的操作,如显示一个错误页面等等
}
});
资源加载等
webView.setWebViewClient (new WebViewClient() {
@Override public void onLoadResource(WebView view, String url) {
//对资源的处理等等
}
});
5、WebChromeClinet类:处理网页的对话框、网站标题等等
获取网站加载进度,用于显示进度条等等
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
}
});
获取网站标题并显示
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onReceivedTitle(WebView view, String title) {
//获取网页标题
}
});
处理js对话框,包括警告框、确认框和输入框, 返回true表示native要处理。
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(final WebView view, String url, String message, JsResult result) {
return super.onJsAlert(view, url, message, result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
return super.onJsConfirm(view, url, message, result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
return super.onJsPrompt(view, url, message, defaultValue, result);
}
});
6、web与native通信
6.1 native调用js
备注:JS代码调用一定要在 onPageFinished() 回调之后才能调用
6.1 js调用native
7、webview缓存机制及资源预加载
7.1 缓存机制
7.2 缓存模式
LOAD_DEFAULT:根据cache-control决定是否从网络中获取数据
LOAD_CACHE_ELSE_NETWORK:只要本地有缓存就使用缓存
LOAD_NO_CACHE:不使用缓存
LOAD_CACHE_ONLY:只读取本地缓存
7.3 webview预加载
webview可提前构建缓存,重复使用
8 webview漏洞问题
8.1 任意代码执行漏洞
WebView 中 addJavascriptInterface() : Android4.2之后被调用函数以@JavascriptInterface注解避免漏洞攻击
WebView 内置导出的 searchBoxJavaBridge_对象
WebView 内置导出的 accessibility 和 accessibilityTraversalObject 对象
8.2 密码明文存储漏洞
webview默认开启密码保存功能,在用户输入密码时会弹出提示框:询问用户是否保存密码,如果是,密码会被明文保存到 /data/data/com.package.name/databases/webview.db中,有密码泄露的风险。
解决方案:关闭密码保存提醒
webSettings.setSavePassword(false);
8.3 域控制不严格漏洞
即 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);
}