apk 和 H5 混合
1.汇总
jsbridge 是 java 和 js 之间的一个桥梁
最主要的就是 两端的通信
安全
效率
覆盖率
解决的问题
1.漏洞问题
2.代码繁琐问题
3.android 接收 js 的回调只支持 android4.4 以上的版本
2.本质问题
1. java 调用 js
2. js 调用 java
原生调用方式
java 调用 js
webView.loadUrl("javascript:alertMsg(" + "'Android传过来的参数'" + ")")
本质:是一个拼接 js 字符串的过程.
但是 loadUrl 不能直接获取返回值,要获取返回值可以通过webview.evaluateJavaScript方法,但是此方法只有 android4.4 及以上才可以使用.
webView.evaluateJavascript("javascript:alertMsg(" + "'Android传过来的参数'" + ")") { s ->
button.text = s
}
js 调用 java
有三种方式 : 对象映射,URL 拦截,js 方法拦截
1.对象映射
就可以在 js 中直接调用 javaObject对象,从而实现此功能.但是此方法在 android4.2 下有安全漏洞,可以利用反射机制调用 android api getRuntime 执行 shell 命令攻击(遍历sdcard、发送短信、安装木马APK等)
android
public class JsInteration {
@JavascriptInterface
public String back() {
return "hello world";
}
}
webView.addJavascriptInterface(new JsInteration(),"android");
js
window.android.back();
这是一次交互,如果是N次呢?
攻击代码
2.url 拦截
通过iframe.src、window.open、documention.location或者href,这四种方法都可以在html页面中打开一个连接,从而会触发Java中的WebViewClient.shouldOverrideUrlLoading方法.
例如:js 中执行
document.location = 'http://www.baidu.com/{"data":{"username":"tom"}}'
webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
Log.e("cml",url)
return super.shouldOverrideUrlLoading(view, url)
}
}
3.js 方法拦截
在JS中调用alert、console、prompt、confirm等方法就会触发WebChromeClient的onJsAlert、onConsoleMessage、onJsPrompt、onJsConfirm方法的回调.
JSbridge
它主要解决的问题就两个
1.回调问题
在java端和js端定义一个数据结构: Message={callbackId:xxx, handleName:xxx,responseData:xxx,responseId:xxx}
将回调函数保存在callbackId中,当JS或者Java处理完数据回调的时候再将保存在callbackId的回调函数存放在responseId,相应的回调的数据存放在responseData中,这样就能响应JS或者Java调用后的回调消息
2.js 调用 android 使用哪种方式
Js调用Java的方法虽然有三种,
addJavaScriptInterface存在安全性问题一般不建议使用,
JS中的alert、console方法都会在Html页面比较常用,confirm和prompt虽然不常用但是某些手机系统版本上会有对话框弹出,不通用.
比较好的选择是url拦截,可以通过iframe.src触发shouldOverrideUrlLoading.
流程图
从 java 看
从 js 看
在H5页面加载完毕注入一个本地的js文件;
Java代码中注册BridgeHandler,用来处理JS发送过来的消息;
在本地注入的js文件中定义_handleMessageFromNative,用来接收java传递过来的消息;
因为客户端注入js是异步的,所以需要在js文件中注册Event监听器,成功后通知H5。