WebView学习笔记
WebView学习笔记,参考最全面、最易懂的Webview使用详解
基本用法
加载内容
1 | webView.loadUrl("http://www.google.com/"); |
加载一个网址
1 | WebView.loadData(String data, String mimeType, String encoding) |
加载一段网络内容,参数1是内容,参数2是内容类型,参数3是编码方式
避免内存泄漏
不在xml中定义,而是需要时创建,使用Application的Context
销毁的时候,先加载空内容,然后移除View,最后销毁
1 | webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); |
WebView调用destroy()
时仍绑定在Activity上,所以要先移除WebView,然后在摧毁
后退
不做处理时,按Back键会使WebView结束掉,所以需要在按键中处理
1 | public boolean onKeyDown(int keyCode, KeyEvent event) { |
常用类
WebSettings
对WebView进行配置管理
1 | WebSettings webSettings = webView.getSettings(); |
如果加载的HTML里有JS在执行动画等操作,会造成资源浪费,在onStop()
和onStart()
里分别把setJavaScriptEnabled()
给设置成false
和true
即可
WebViewClient
处理各种通知/事件
1 | public boolean shouldOverrideUrlLoading(WebView view, String url) { |
载入Url之前可以在这里获得控制进行处理,不提供时,由系统选择如何处理Url(在浏览器中打开),返回false
则由系统处理,返回true
由应用处理
1 | webView.setWebViewClient(new WebViewClient(){ |
以上是在本WebView显示而不打开新的浏览器
1 | // 开始载入页面 |
WebChromeClient
辅助处理JS,图标,标题等
1 | public void onProgressChanged(WebView view, int newProgress) {} |
JS和Android代码的交互
Android调用JS
loadUrl()
1 | mWebView.loadUrl("javascript:callJS()"); |
调用JavaScript中的callJS()
方法
JS代码调用一定要在onPageFinished()
回调之后才能调用,否则不会调用
evaluateJavascript()
1 | mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() { |
这个方法不会刷新页面,所以比较高效,可以处理返回值,4.4
以上才可以用
JS调用Android
addJavascriptInterface()对象映射
定义映射关系类,把JS需要调用的方法用@JavascriptInterface
注释,代码中用addJavascriptInterface()
添加映射
Android2JS.java
1 | public class Android2JS extends Object { |
1 | mWebView.addJavascriptInterface(new Android2JS(), "android2js"); |
1 | <script> |
这样就可以通过JS调用原生代码
JS拿到Android对象后,可以调用对象中的所有方法,是严重的安全漏洞
对象可以通过
getClass()
获得当前类Class,通过Class.forName()
可以加载类,如果加载了Runtime
类,便可以执行本地命令,比如访问文件APP通过扫描等打开外部网页,可能运行到恶意攻击代码
4.2
之后可以通过加@JavascriptInterface
注释
4.2
之前通过拦截prompt()
修复(不很理解,感觉跟下面的差不多)
shouldOverrideUrlLoading()方法回调拦截
1 | <script> |
JS里面的函数修改location
,然后通过shouldOverrideUrlLoading()
拦截URL路由
1 |
|
只能通过加载执行JS代码返回值,比较麻烦
1 | mWebView.loadUrl("javascript:returnResult(" + result + ")"); |
拦截JS对话框alert()、confirm()、prompt()消息
跟拦截URL差不多,而且使用输入框可以方便的返回值
1 |
|
漏洞
任意代码执行漏洞
addJavascriptInterface()
searchBoxJavaBridge_
3.0
以下,系统默认添加映射对象searchBoxJavaBridge_
,可能被利用,用removeJavascriptInterface()
删除该方法就好了
accessibility
和accessibilityTraversal
同上
密码明文存储
WebView默认开启密码保存,并明文保存到本地数据库,通过WebSettings.setSavePassword(false)
关闭密码保存
域控制不严格
A应用可以通过B应用导出的Activity让B应用加载一个恶意的file
协议的URL,从而可以获取B应用的内部私有文件,从而带来数据泄露威胁
使用file
域加载的JS代码能够使用进行同源策略跨域访问,从而导致隐私信息泄露
通过WebSettings.setAllowFileAccess(true)
禁止访问文件,缺点是这样就不能加载本地网页,可以对使用file
协议的URL禁止使用JS
通过WebSettings.setAllowFileAccessFromFileURLs(false)
禁止file
协议加载的JS访问本地文件
通过WebSettings.setAllowUniversalAccessFromFileURLs(false)
禁止file
协议加载的JS访问其他Http源等
总之对不需要file
协议的禁用file
协议,需要用的禁用JS