说明
Hybrid模式原生和H5交互原理
目录
前言
参考来源
前人栽树,后台乘凉,本文参考了以下来源
前置技术要求
阅读本文前,建议先阅读以下文章
楔子
Hybrid APP的关键是原生页面与H5页面直接的交互,本文做简单介绍
Android、iOS原生和H5的基本通信机制
在Hybrid APP中,原生与H5的交互方式在Android和iOS上的实现是有异同的,原因是Android、iOS的通信机制有所区别,下面介绍原生和H5相互调用的方法
Android端
Native调JS
4.4版本之前
// mWebView = new WebView(this); //即当前webview对象
mWebView.loadUrl("java script: 方法名('参数,需要转为字符串')");
//ui线程中运行
runOnUiThread(new Runnable() {
@Override
public void run() {
mWebView.loadUrl("java script: 方法名('参数,需要转为字符串')");
Toast.makeText(Activity名.this, "调用方法...", Toast.LENGTH_SHORT).show();
}
});
4.4以后(包括4.4)
//异步执行JS代码,并获取返回值
mWebView.eva luatejava script("java script: 方法名('参数,需要转为字符串')", new ValueCallback() {
@Override
public void onReceiveva lue(String value) {
//这里的value即为对应JS方法的返回值
}
});
如上所示,Native用H5页面中的JS方法,有如下特点
- 4.4之前Native通过loadUrl来调用JS方法,只能让某个JS方法执行,但是无法获取该方法的返回值
- 4.4之后,通过eva luatejava script异步调用JS方法,并且能在onReceiveva lue中拿到返回值
- 不适合传输大量数据(大量数据建议用接口方式获取)
- mWebView.loadUrl("java script: 方法名('参数,需要转为字符串')");函数需在UI线程运行,因为mWebView为UI控件(但是有一个坏处是会阻塞UI线程)
JS调Native
WebSettings webSettings = mWebView.getSettings();
//Android容器允许JS脚本,必须要
webSettings.setjava scriptEnabled(true);
//Android容器设置侨连对象
mWebView.addjava scriptInterface(getJSBridge(), "JSBridge");
Android中JSBridge的代码
//Android4.2版本以上,本地方法要加上注解@java scriptInterface,否则会找不到方法。
private Object getJSBridge(){
Object insertObj = new Object(){
@java scriptInterface
public String foo(){
return "foo";
}
@java scriptInterface
public String foo2(final String param){
return "foo2:" + param;
}
};
return insertObj;
}
Html中JS调用原生的代码
//调用方法一
window.JSBridge.foo(); //返回:'foo'
//调用方法二
window.JSBridge.foo2('test');//返回:'foo2:test'
如上所示,Native中通过addjava scriptInterface添加暴露出来的JS桥对象,然后再该对象内部声明对应的API方法,有如下特点:
iOS端
Native调JS
//可以取得JS函数执行的返回值
//方法必须是Html页面绑定在最顶层的window上对象的
//如window.top.foo
//Swift
webview.stringByeva luatingjava scriptFromString("方法名(参数)")
//OC
[webView stringByeva luatingjava scriptFromString:@"方法名(参数);"];
如上所示,Native通过stringByeva luatingjava scriptFromString调用Html绑定在window上的函数,有如下特点
- Native调用JS方法时,能拿到JS方法的返回值
- 不适合传输大量数据(大量数据建议用接口方式获取)
JS调Native
引入官方的库文件
#import <java scriptCore/java scriptCore.h>
Native注册api函数(OC)
//webview加载完毕后设置一些js接口
-(void)webViewDidFinishLoad:(UIWebView *)webView{
[self hideProgress];
[self setJSInterface];
}
-(void)setJSInterface{
JSContext *contex