关于Android 和 h5 hybrid 开发的实践在网上有很多,Android自身就有一个webview,很多实践都是通过webview来实现的,以下是记录一下自己的实践。
1、Android与H5通讯方式
主要有两种:有基于url拦截的,也有基于prompt拦截的。 Android上面最火的这个开源项目 JsBridge就是基于url来进行拦截的
2、JsBridge原理和用法
原理 Android调用H5:通过webview类的loadUrl方法可以直接执行js代码,类似浏览器地址栏输入一段js一样的效果
webview.loadUrl("javascript: alert('hello world')");
H5调用Android:webview可以拦截H5发起的任意url请求,webview通过约定的规则对拦截到的url进行处理(消费),即可实现H5调用Android
var ifm = document.createElement('iframe');
ifm.src = 'jsbridge://namespace.method?[...args]';
JsBridge上面已经封装了一层协议了,关于协议的设置我们之前有这篇文章Android自定义UrlSchema。所以如果要自定义一套协议的话,可以参考下面这个方式
schema://classname/method?value={} // Android会收到这个url
schema即自行约定的私有协议,一般是公司名或者应用名
classname/method这两个一起,指定API名称,classname可以是Android的类名,当然也可以只是一个普通字符串(如namespace),只要Android方便识别即可
value是与method对应的参数
请求示例:
// H5直接指定包名和方法名,这样更容易扩展
iframe.src = `myschema://com.mycompany.hybrid.InteractHandler/toast?value={msg: 'hello world'}`
// 用约定的字符串也可以,Android拿到之后自己再做一次map
iframe.src = `myschema://interact/toast?value={msg: 'hello world'}
JsBridge用法1:
java注册handler方法以供h5里面的js调用
webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
Log.i(TAG, "handler = submitFromWeb, data from web = " + data);
function.onCallBack("submitFromWeb exe, response data from Java");
}
});
js可以通过下面的方式调用这个的java handler的“submitFromWeb”方法
WebViewJavascriptBridge.callHandler(
'submitFromWeb'
, {'param': str1}
, function(responseData) {
document.getElementById("show").innerHTML = "send get responseData from java, data = " + responseData
}
);
JsBridge用法2:
js注册handler方法以供Java里面的代码调用
WebViewJavascriptBridge.registerHandler("functionInJs", function(data, responseCallback) {
document.getElementById("show").innerHTML = ("data from Java: = " + data);
var responseData = "Javascript Says Right back aka!";
responseCallback(responseData);
});
java里面可以通过以下方式来调用这个js handler的“functionInJs"方法
webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
@Override
public void onCallBack(String data) {
}
});
3、使用过程中的问题
1、最主要有一个是性能问题,通过iframe的src来进行跳转会遇到加载慢的问题,存在js已经加载完了,但是bridge还没有ready的情况,以至于有些情况下前端任务这个时间差太长了
2、是否存在jsbridge加载失败,可以通过cookiemanager传递一些内容?
3、用户信息的传递,通过token来传递
4、js中如何加上权限控制?java中如何控制js中代码的权限? 参考各种h5类型的开放平台实现
4、结语
性能问题可以考虑不采用url方式,而采用promt方式来实现?