###1、Webview的最常用的工具类: WebViewClient类、WebChromeClient类
###1.1、WebViewClient类
WebViewClient主要用来辅助WebView处理各种通知、请求等事件
onLoadResource onPageFinished onPageStarted onReceivedError shouldOverrideUrlLoading
若没有设置 WebViewClient 则由系统(Activity Manager)处理该 url,通常是使用浏览器打开或弹出浏览器选择对话框。 若设置 WebViewClient 且该方法返回 true ,则说明由应用的代码处理该 url,WebView 不处理,也就是程序员自己做处理。 若设置 WebViewClient 且该方法返回 false,则说明由 WebView 处理该 url,即用 WebView 加载该 url。
###1.2、WebViewClient类WebChromeClient类
WebChromeClient主要用来辅助WebView处理Javascript的对话框、网站图标、网站标题以及网页加载进度等。
onProgressChanged onReceivedTitle onJsAlert onConsoleMessage
###2、Android执行JS代码的方法有2种:
###2.1、通过WebView的loadUrl()
优势:无版本限制
缺点是无法在JS代码执行完成之后,进行回调。 可通过在JS代码尾端打印完成的consoleMessage,我们通过WebChromeClient的onConsoleMessage去监听这个message,执行相应回调。
###2.2、通过WebView的evaluateJavascript() 缺点:4.4以上版本才能使用。 优势:可以传入一个回调对象,JS代码执行完成之后,可直接回调。
为了版本兼容,两种方式可配合使用。 4.4以上版本使用evaluateJavascript(),以下使用loadUrl() 。
###3、JS调用Android代码的方法有3种:
###3.1、通过WebView的addJavascriptInterface()进行对象映射 缺点:Android 4.2 版本以下存在安全漏洞
webView.addJavascriptInterface(new JSObject(), "myObj");
myObj.getClass().forName(" java.lang.Runtime “)
function execute(cmdArgs)
{
// 步骤1:遍历 window 对象
// 目的是为了找到包含 getClass ()的对象
// 因为Android映射的JS对象也在window中,所以肯定会遍历到
for (var obj in window) {
if ("getClass" in window[obj]) {
// 步骤2:利用反射调用forName()得到Runtime类对象
alert(obj);
return window[obj].getClass().forName("java.lang.Runtime")
// 步骤3:以后,就可以调用静态方法来执行一些命令,比如访问文件的命令
getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
// 从执行命令后返回的输入流中得到字符串,有很严重暴露隐私的危险。
// 如执行完访问文件的命令之后,就可以得到文件名的信息了。
}
}
}
Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
###3.2、 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
###3.3、 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息
特别注意:JS代码调用一定要在 onPageFinished() 回调之后才能调用,否则不会调用。
###4、Android WebView自带的缓存机制有5种: 浏览器 缓存机制 Application Cache 缓存机制 Dom Storage 缓存机制 Web SQL Database 缓存机制 Indexed Database 缓存机制
WebView缓存对于android端来说只需要调用对应方法开启就行了,具体使用缓存由h5页面完成
###5、WebView内存泄漏
泄漏引用链:mComponentCallbacks->AwContents->BaseWebView->BookDetailActivity
WebView在onAttachedToWindow中会向application注册一个mComponentCallbacks,以监听内存不足等情况。 在onDetachedFromWindow时会反注册,但是反注册的前提是webview没有destory。
所有我们在调用WebView.destroy()之前需要将WebView从其父容器中移除。
ViewParent parent = mWebView.getParent();
if (parent != null) {
((ViewGroup) parent).removeView(mWebView);
}
mWebView.destroy();
if (isDestroyed()) return;