网页H5,中间层JSBridge,原生Native
一.网页(H5)和原生(Native)之通信原理:
- 网页(H5)调用原生(Native):网页H5->通过一个对象和方法(这个对象和方法是原生Native通过各个原生系统提供的方法保存到网页H5环境的,这个就是所谓的原生注入对象到网页)->传入参数调用网页H5环境的原生注入对象->触发绑定在原生端的对象和方法执行->最后结束执行->通过原生提供的方法把结果入栈
- 原生(Native)调用网页(H5):原生Native->通过原生Native的H5解释机制对象(也就是把要执行的网页H5代码放在一个字符串里,直接给原生Native的H5解释机制对象让它执行)->最后结束执行->通过原生提供的方法把结果入栈
- 通俗一点讲:网页H5->通过一个内存地址访问->原生Native->通过一个内存地址访问->网页H5
二.框架层级:
1.网页(H5):
- 可以有很多个,每个都是独立内存的,也就是可以有两个一样的网页h5应用互不影和冲突
2.中间层(JSBridge):
- 起到网页(H5)和原生(Native)之间的调用和注入对象的管理
3.原生(Native):
- 各个系统创建出来的原生应用
三.对应关系:
- m个网页(H5)<–>1个原生(Native),m个网页(H5)<–>n个中间层(JSBridge),1个原生(Native)<–>n个中间层(JSBridge)
四.具体实现:
1.网页(H5)调用原生(Native)
-
对象方式:Native部分创建一个JS对象,向WebView注入JS对象,这样JS就可以直接用这个对象了。如:原生代码 webView.addJavascriptInterface(new JSNativeBridge(webView),“H5NativeBridge”);//JS代码就可以用这个名叫H5NativeBridge对象了(addJavascriptInterface这个方法是安卓系统的,其它系统是不一样方法)
-
URL方式:Native部分通过原生的监听WebView发来的URL请求方法来解释地址的内容(如shouldoverrideurlloading就是安卓的WebView监听URL方法,不同的系统有不同的WebView监听方法),再跟据对应的内容执行不同的功能
2.原生(Native)调用网页(H5)
- H5解释机(也叫js解释组件)方式
如:原生代码 webView.evaluateJavascript(“console.log(‘test’)”, null);//evaluateJavascript是安卓系统的js解释方法,其它系统的不一样,而console.log(‘test’)是js的代码
3.dart代码示例
对象方式:
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:convert';
//自定义WebViewController
class MyWebViewController extends WebViewController {
var mJSNativeBridge;//保存自定义数据
/**
* 绑定JSNativeBridge
*/
bindJSNativeBridge(JSNativeBridge pJSNativeBridge){
mJSNativeBridge = pJSNativeBridge;
mJSNativeBridge.bindMyWebViewController(this);
this.addJavaScriptChannel('H5NativeBridge', onMessageReceived:(message){
print('收到来自js的消息是:${message.message}');
mJSNativeBridge.H5CallNative(message.message);
});
return this;
}
}
class JSNativeBridge {
var mMyWebViewController;//保存自定义数据
/**
* 绑定MyWebViewController
*/
bindMyWebViewController(MyWebViewController pMyWebViewController) {
mMyWebViewController = pMyWebViewController;
}
/**
* 网页(H5)调用原生(Native)方法
*/
H5CallNative(String params){
var paramsItem = jsonDecode(params);
switch (paramsItem.func) {
case 'ShowNativeView':
//这里调用原生的显示view方法 可以把paramsItem作为参数传入
break;
default:
break;
}
}
/**
* 原生(Native)调用网页(H5)方法
*/
NativeCallH5(String func, String dataStr) {
//等于js调用: func(dataStr);
this.mMyWebViewController.runJavaScript(func+"("+dataStr+")");
}
static creatWebView(){
//创建WebViewWidget
WebViewWidget t_webViewWidget = WebViewWidget(
controller: MyWebViewController().bindJSNativeBridge(JSNativeBridge()),
);
return t_webViewWidget;
}
}
URL方式:
import 'package:webview_flutter/webview_flutter.dart';
class JSNativeBridge {
/**
* 绑定网页(H5)调用原生(Native)方法
*/
static bindH5CallNative(WebViewController pWebViewController) {
pWebViewController.setNavigationDelegate(
NavigationDelegate(onNavigationRequest: (request) {
if (request.url.startsWith('H5CallNative://ShowNativeView/')) {
List t_list = request.url.split('H5CallNative://ShowNativeView/');
var paramsItem = t_list[1];
//
//这里调用原生的显示view方法 可以把paramsItem作为参数传入
return NavigationDecision.navigate;
}
return NavigationDecision.prevent;
}));
}
/**
* 原生(Native)调用网页(H5)方法
*/
static NativeCallH5(WebViewController pWebViewController,String func, String dataStr) {
//等于js调用: func(dataStr);
pWebViewController.runJavaScript(func+"("+dataStr+")");
}
}