APP开发模式有以下四大类型:
-
Weex
-
Native App
即传统的原生APP开发模式,Android基于Java语言,底层调用Google的 API;iOS基于OC或者Swift语言,底层调用App官方提供的API。体验最后。
- Web App
即移动端的网站,将页面部署在服务器上,然后用户使用各大浏览器访问。一般泛指 SPA(Single Page Application)模式开发出的网站。体验最差。
- Hybrid App
即混合开发,由Native通过JSBridge等方法提供统一的API,然后用Html5+JS来写实际的逻辑,调用API,这种模式下,由于Android,iOS的API一般有一致性,而且最终的页面也是在webview中显示,所有有跨平台效果
这种模式可以用原生来实现要求高的界面,对于一些比较通用型,展示型的页面完全可以用web来实现,达到跨平台效果,提升效率
原理:Hybird实现的基本原理是通过原生的WebView容器加载H5网页进行渲染,通过JavaScript Bridge调用一部分系统能力,同步更新服务器上的H5网页也实现了动态更新,俗称混合应用。
- React Native App
使用JS+部分原生语法来实现功能。初次学习成本较高,但是在入门后,经过良好的封装也能够实现大部分的跨平台。而且体验很好。
原生和H5的一种通讯方式:JSBridge
定义:JSBridge就是定义Native和JS的通信,Native只通过一个固定的桥对象调用JS,JS也只通过固定的桥对象调用Native。
基本原理:H5->通过某种方式触发一个url->Native捕获到url,进行分析->原生做处理->Native调用H5的JSBridge对象传递回调。
JavaScript 调用 Native:
JavaScript 调用 Native 的方式,主要有两种:注入 API 和 拦截 URL SCHEME。
- 拦截url scheme介绍:
url scheme是一种类似于url的链接,是为了方便app直接互相调用设计的
可以用系统的OpenURI打开一个类似于url的链接(可拼入参数),然后系统会进行判断,如果是系统的url scheme,则打开系统应用,否则找看是否有app注册这种scheme,打开对应app
需要注意的是,这种scheme必须原生app注册后才会生效。
实现思路:
- 第一步:设计出一个Native与JS交互的全局桥对象
- 第二步:JS如何调用Native
- 第三步:Native如何得知api被调用
- 第四步:分析url-参数和回调的格式
- 第五步:Native如何调用JS
- 第六步:H5中api方法的注册以及格式
第一步:设计出一个Native与JS交互的全局桥对象
- JS和Native之间的通信必须通过一个H5全局对象JSbridge来实现,该对象有如下特点
该对象名为"JSBridge",是H5页面中全局对象window的一个属性
var JSBridge = window.JSBridge || (window.JSBridge = {});
- 该对象有如下方法
-
registerHandler( String,Function )H5调用 注册本地JS方法,注册后Native可通过JSBridge调用。调用后会将方法注册到本地变量messageHandlers 中
-
callHandler( String,JSON,Function )H5调用 调用原生开放的api,调用后实际上还是本地通过url scheme触发。调用时会将回调id存放到本地变量responseCallbacks中
-
_handleMessageFromNative( JSON )Native调用 原生调用H5页面注册的方法,或者通知H5页面执行回调方法
第二步:JS如何调用Native
定义好了全局桥对象,可以通过它的callHandler方法来调用原生的。
callHandler函数内部实现过程:
(1)判断是否有回调函数,如果有,生成一个回调函数id,并将id和对应回调添加进入回调函数集合responseCallbacks中
(2)通过特定的参数转换方法,将传入的数据,方法名一起,拼接成一个url scheme
//url scheme的格式如
//基本有用信息就是后面的callbackId,handlerName与data
//原生捕获到这个scheme后会进行分析
var uri = CUSTOM_PROTOCOL_SCHEME://API_Name:callbackId/handlerName?data
(3)使用内部早就创建好的一个隐藏iframe来触发scheme
//创建隐藏iframe过程
var messagingIframe = document.createElement('iframe');
messagingIframe.style.display = 'none';
document.documentElement.appendChild(messagingIframe);
//触发scheme
messagingIframe.src = uri;
第三步:Native如何得知api被调用
上一步中,我们已经成功在H5页面中触发scheme,那么Native如何捕获scheme被触发呢?
Android捕获url scheme
在Android中(WebViewClient里),通过shouldoverrideurlloading可以捕获到url scheme的触发
public boolean shouldOverrideUrlLoading(WebView view, String url){
//读取到url后自行进行分析处理
//如果返回false,则WebView处理链接url,如果返回true,代表WebView根据程序来执行url
return true;
}
Android中也可以不通过iframe.src来触发scheme,android中可以通过window.prompt(uri, "");来触发scheme,然后Native中通过重写WebViewClient的onJsPrompt来获取uri.
第四步:分析url-参数和回调的格式
Native接收到Url后,可以按照这种格式将回调参数id、api名、参数提取出来,然后按如下步骤进行:
(1)根据api名,在本地找寻对应的api方法,并且记录该方法执行完后的回调函数id
(2)根据提取出来的参数,根据定义好的参数进行转化
(3)原生本地执行对应的api功能方法
(4)功能执行完毕后,找到这次api调用对应的回调函数id,然后连同需要传递的参数信息,组装成一个JSON格式的参数
(5)通过JSBridge通知H5页面回调
第五步:Native如何调用JS
//将回调信息传给H5
JSBridge._handleMessageFromNative(messageJSON);
-
Native通知H5页面进行回调
-
Native主动调用H5方法 数据格式是:{handlerName:api名,data:数据,callbackId:回调id}
第六步:H5中api方法的注册以及格式
H5中注册供原生调用的API:
//注册一个测试函数
JSBridge.registerHandler('testH5Func',function(data,callback){
alert('测试函数接收到数据:'+JSON.stringify(data));
callback&&callback('测试回传数据...');
});