-- WebView形象的理解上述流程从一个loadUrl来看,详细流程如下:
Browser.loadUrl->WebView.loadUrl->WebViewChromium.loadUrl->AwContents.loadUrl->ContentViewCore.loadUrl。
-- webview有两个方法:setWebChromeClient 和 setWebClient:
setWebClient:主要处理解析,渲染网页等浏览器做的事情,WebViewClient就是帮助WebView处理各种通知、请求事件的;
setWebChromeClient:辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等。
android WebView详解,常见漏洞详解和安全源码- https://blog.csdn.net/self_study/article/details/54928371
Android基于JsBridge封装的高效带加载进度的WebView- https://blog.csdn.net/sk719887916/article/details/52402470
Android中WebView的JavaScript代码和本地代码交互的三种方式- https://blog.csdn.net/jiangwei0910410003/article/details/52687530
腾讯正式开源高性能Hybrid框架VasSonic- https://github.com/Tencent/vassonic
-- 在PC端用谷歌浏览器调试android webView中的html页面:https://blog.csdn.net/qq229466182/article/details/78708595
首先,此处的html页面是指在webView加载运行的。
android在4.4版本及以上,使用了Chromium作为webView的内核支持,这也使得我们
可以在pc端的chrome浏览器对运行在webView里的html进行调试,首先要在webView设置中加如下代码
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
webView.setWebContentsDebuggingEnabled(true);
}
chrome://inspect/#pages
> Js与Native通信
- Js通知Native目前有三种方案。
1.API注入。通过webview.addJavascriptInterface()的方法实现。
2.拦截Js的alert/confirm/prompt/console等事件。由于prompt事件在js中很少使用,所以一般是拦截该事件。这些事件在WebChromeClient都有对应的方法回调(onConsoleMessage,onJsPrompt,onJsAlert,onJsConfirm)
3.url跳转拦截,对应WebViewClient的shouldOverrideUrlLoading()方法。
第一种方法,由于webview在4.2以下的安全问题,所以有版本兼容问题。后两种方法原理本质上是一样的,都是通过对webview信息冒泡传递的拦截,通过定制协议-拦截协议-解析方法名参数-执行方法-回调。
- Native通知Js
webview可以通过loadUrl()的方法直接调用。在4.4以上还可以通过evaluateJavascript()方法获取js方法的返回值。
4.4以前,如果想获取方法的返回值,就需要通过上面的对webview信息冒泡传递拦截的方式来实现。
> Hybrid App
-- MUI 框架 :https://github.com/dcloudio/mui ;html+css+js就能开发app的框架
MUI,react native对比有什么区别?react native只使用js,而Mui这套使用的是html+css+js。两者区别最大是no HTML5 和 h5+。这点对于渲染方式要及其大的区别。react native也就是使用js语言编程,但不使用浏览器引擎渲染,而是用独立v8引擎解析指定的js语法,然后由js操作绘制界面。而h5+主要就是靠webview来渲染html界面的。这个渲染方面的区别,还有就是react native是学一套做一套模式,这点就是学ios写ios app,学andriod写android app。这点和Mui app一套双平台,有所区别。
MUI,superwebview对比有什么区别?之前看到我国开发的另一款 Hybrid App 框架,api不够Mui的多,社区活跃度差点。但我有空也会用它来重构一下,支持一下我国开发项目。
MUI蓝牙打印(Android)- https://blog.csdn.net/mss359681091/article/details/82111872
-- SuperWebView 记录 遇到的问题解决方案-https://www.jianshu.com/p/838f193fb7d9
APICloud SuperWebView融合Android原生平台- https://blog.csdn.net/MeetYourMaster/article/details/81137344
-- JsBridge 混合开发
WebView中的网页进行交互,点击网页通过接口进行原生处理,
Android中使用WebView与JS交互全解析- http://blog.csdn.net/u012124438/article/details/53371102
Android中使用WebView与JS交互全解析- http://blog.csdn.net/jdsjlzx/article/details/51376739
为WebView中的Java与JavaScript提供【安全可靠】的多样互通方案- https://github.com/pedant/safe-java-js-webview-bridge
关于腾讯浏览器服务Android X5WebView的Demo- https://github.com/EUEHBin/X5WebViewDemo
-- 基于https://github.com/lzyzsd/JsBridge 优化改进而来的Android JsBridge
1.基于系统的JsBridge; 2.基于Tbs X5内核的JsBridge
优化改进而来的Android JsBridge- https://github.com/hjhrq1991/JsBridge
-- (推荐)H5与原生通信,JsBridge- https://github.com/lzyzsd/JsBridge
if (callback != null) {
myInterface.addCallback(++uniqueId + "", callback);
webView.loadUrl("javascript:window." + kInterface+ ".onResultForScript(" + uniqueId + "," + script + ")");
} else {
webView.loadUrl("javascript:" + script);
}
JSBridge框架,JS和native通信的桥梁- https://github.com/firewolf-ljw/WebViewJSBridge
Android 各个版本WebView- http://blog.csdn.NET/typename/article/details/40425275
webview实现h5视频全屏播放兼容Android7.0,兼容全部版本-http://blog.csdn.net/insist_hui/article/details/58172859
Android实现微信webview兼容Android 7.0- https://github.com/lshAndroid/WebviewTBS/tree/master
JsBridge实现Js与Java的互相调用- https://github.com/lzyzsd/JsBridge
WebViewJavascriptBridge框架- https://github.com/marcuswestin/WebViewJavascriptBridge
> 拦截网络webview URL请求
webview拦截请求- http://blog.csdn.net/knxw0001/article/details/10903055
Android 拦截WebView加载URL,控制其加载CSS、JS资源- http://blog.csdn.net/lyhhj/article/details/49517537
Android中WebView拦截js请求- http://blog.csdn.net/wang8651971/article/details/45584117
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.startsWith(kCustomProtocolScheme)) {
if (url.indexOf(kQueueHasMessage) > 0) {
flushMessageQueue();
}
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
//TODO
String fileName = null;
WebResourceResponse response = null;
if (url.contains("logo")) {
try {
InputStream localCopy = NyApplication.getInstance().getAssets().open("droidyue.png");
response = new WebResourceResponse("image/png", "UTF-8", localCopy);
} catch (IOException e) {
e.printStackTrace();
}
}
if(url.contains("/base.css")){
LogUtil.e(",WVJBWebViewClient,shouldOverrideUrlLoading()","url="+url);
// webView.loadUrl("file:///android_asset/pages/css/base.css");
}else if(url.contains("/netyun/css/textitem.css")){
LogUtil.e(",WVJBWebViewClient,shouldOverrideUrlLoading()","url="+url);
// webView.loadUrl("file:///android_asset/pages/css/textitem.css");
}else if(url.contains("/js/item.js")){
LogUtil.e(",WVJBWebViewClient,shouldOverrideUrlLoading()","url="+url);
// webView.loadUrl("file:///android_asset/pages/js/item.js");
}else if(url.contains("/libs/requirejs/require.js")){
LogUtil.e(",WVJBWebViewClient,shouldOverrideUrlLoading()","url="+url);
// webView.loadUrl("file:///android_asset/pages/js/require.js");
}else{
}
try {
InputStream localCopy = NyApplication.getInstance().getAssets().open("droidyue.png");
response = new WebResourceResponse("image/png", "UTF-8", localCopy);
}catch (IOException e) {
e.printStackTrace();
}
return response;
// return super.shouldInterceptRequest(view, url);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return super.shouldInterceptRequest(view, request);
}
> WebView中WebViewClient和WebChromeClient区别与联系
-- WebViewClient和WebChromeClient
WebViewClient用于帮助WebView处理各种通知和请求事件;
WebChromeClient更丰富一些,帮助WebView处理Javascript各类对话框、弹窗等等。
Hybrid App知识点收集- http://blog.csdn.net/qq_27429143/article/details/78916163
1.拦截JS对话框 WebView.setWebChromeClient(new WebChromeClient(){});
2. WebView拦截某一个链接不执行此链接或拦截URL或拦截H5页面点击之后的URL
Android webView拦截url- http://blog.csdn.net/u010694658/article/details/52388287
// 此回调是拦截点击要跳转的url链接,并对请求的url链接做修改(添加删除字段)
public WebResourceResponse shouldInterceptRequest(WebView view, String url)
// 在点击请求的是链接是才会调用,重写此方法返回true表明点击网页里面的链接还是在当前的webview里跳转,不跳到浏览器那边。这个函数我们可以做很多操作,比如我们读取到某些特殊的URL,于是就可以不打开地址,取消这个操作,进行预先定义的其他操作,这对一个程序是非常必要的。
public boolean shouldOverrideUrlLoading(WebView view, String url)
1.WebViewClient比较基础的方法,帮助WebView处理各种通知和请求事件;
//处理webView的按键事件
boolean shouldOverrideKeyEvent(WebView view, KeyEvent event)
//截取url请求,在当前视图加载,避免在跳转到自带浏览器
boolean shouldOverrideUrlLoading(WebView view, String url)
//WebView改变时调用
void onScaleChanged(WebView view, float oldScale, float newScale)
//对https的请求处理
void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)
//获取返回信息授权
void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
//处理报错信息(API23以后用第二个)
void onReceivedError(WebView view, int errorCode, String description, String failingUrl)
void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error)
//页面开始载入时调用
void onPageStarted(WebView view, String url, Bitmap favicon)
//页面载入结束时调用
void onPageFinished(WebView view, String url)
//加载资源时调用
void onLoadResource(WebView view, String url)
webView.setJavaScriptEnabled(true)影响Activity的生命周期
//Agent设置
// WebSettings webSettings = wvPagePV.getSettings();
// wvPagePV.getSettings().setJavaScriptEnabled(true); // 支持js互调,影响Activity的生命周期
wvPagePV.getSettings().setUserAgentString(wvPagePV.getSettings().getUserAgentString() + "/baidu.com/" + MyUtils.getVersionName(mContext));
wvPagePV.loadUrl(newsDetail.newsUrl);
wvPagePV.setWebViewClient(new WebViewClient(){//拦截URL请求或页面点击
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
LogUtil.e("desaco","url="+url);
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
LogUtil.e("desaco","onPageStarted()");
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
LogUtil.e("desaco","onPageFinished()");
super.onPageFinished(view, url);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
@Override
public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
super.onReceivedClientCertRequest(view, request);
}
});
2.WebChromeClient比较基础的方法,帮助WebView处理Javascript各类对话框、弹窗等
//webview关闭时调用void onCloseWindow(WebView window)
//Js的弹窗boolean onJsAlert(WebView view, String url, String message, JsResult result)
//Js提示框boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result)
//Js确认框boolean onJsConfirm(WebView view, String url, String message, JsResult result)
//加载进度void onProgressChanged(WebView view, int newProgress)
//全屏模式(API18以后用第二种)onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
onShowCustomView(View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback)
wvPagePV.setWebChromeClient(new WebChromeClient() {//拦截JS对话框
@Override
public void onProgressChanged(WebView view, int progress) {
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
@Override
public boolean onJsAlert(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);
}
@Override
public boolean onJsTimeout() {
return super.onJsTimeout();
}
@Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
return super.onConsoleMessage(consoleMessage);
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
});
3. WebView未开放的重写方法,比如如下:
// For Android 3.0+
public void openFileChooser(ValueCallback<Uri> uploadMsg) {...}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {...}
// For Android 4.1
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {...}
// For Android 5.0+
public boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback,
WebChromeClient.FileChooserParams fileChooserParams) {
return true;
}
4. webView的安全漏洞
webView常见漏洞以及解决方法- http://blog.csdn.net/fulai00/article/details/52921779
Android4.2下 WebView的@addJavascriptInterface漏洞解决方案- http://blog.csdn.net/zhouyongyang621/article/details/47000041
JS与WebView交互存在的一些问题- http://www.jianshu.com/p/93cea79a2443
在Android系统4.3.1~3.0版本,系统webview默认添加了searchBoxJavaBridge_接口,如果未移除该接口可能导致低版本Android系统远程命令执行漏洞;
修复建议:判断系统版本,显式调用removeJavascriptInterface方法移除searchBoxJavaBridge_接口;
// 在Android系统4.3.1~3.0版本,系统webview默认添加了searchBoxJavaBridge_接口,如果未移除该接口可能导致低版本Android系统远程命令执行漏洞
//如果真的需要没有这些漏洞的话,你可以尝试用腾讯的X5内核,和WebView用法一样。
removeJavascriptInterface("searchBoxJavaBridge_");
removeJavascriptInterface("accessibility") ;
removeJavascriptInterface("accessibilityTraversal");
if(Build.VERSION.SDK_INT == 18){
mWebView.removeJavascriptInterface("searchBoxJavaBridge_");
}
if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT < 17) {
try {
webView.removeJavascriptInterface("searchBoxJavaBridge_");
webView.removeJavascriptInterface("accessibility");
webView.removeJavascriptInterface("accessibilityTraversal");
} catch (Throwable tr) {
tr.printStackTrace();
}
}