不会解耦Hybrid,你扯什么H5跨平台开发?

12842279-72123ee2472968ad
image

跨平台,是HTML5最重要的能力之一。而Hybrid H5因强依赖于具体App,往往不具有跨平台性。这时,将强依赖关系解耦,即可恢复HTML5的跨平台能力。

▎****Hybrid H5跨平台性

✲ Hybrid H5,即混合了原生能力的HTML5。区别于纯粹Web端的HTML5,它可调用原生的能力,强依赖于具体原生App,与原生共同构建整个App的UI层,是App UI层很好的灵活性补充。微信和手Q上的HTML5业务一般都属于Hybrid H5的范畴。

✲ 跨平台性,即一个HTML5页面可同时运行在多个平台上。可运行平台越多,跨平台性就越强。在如今移动互联网的发展大潮中,HTML5能与体验更优的原生终端齐步并进,其跨平台性可谓功不可没。

因强依赖于具体App,Hybrid H5便丧失了跨平台的特性。

我们将从Hybrid H5与原生的通讯原理出发,逐步探讨如何通过解耦来恢复Hybrid H5的跨平台性。

▎****Hybrid H5与原生的通讯原理

12842279-485a5cbe20cb4c23
image

Hybrid H5页面与原生应用的通讯原理图

从原理图中,有四个关键点:一个通讯媒介——原生自定义的通讯协议,以及围绕着通讯媒介执行的三个通讯行为——触发、调用、回调。

关键点详解

1.通讯媒介——原生通讯协议:原生自定义的伪协议,一般会定义成与HTTP协议类似的格式:

12842279-ae6d557d6096b25e
image

其中:

(1)协议名:APP自定义的协议名,用于HTML5触发行为的监控捕获,如手Q使用的 jsbridge://;

(2)接口路径:原生具体能力路径,不同原生能力路径不同;

(3)参数1=XXX&参数2=XXX&参数3=XXX#callback:HTML5传参与回调方法标识;

根据通讯协议规范,即可针对不同的原生能力给HTML5提供不同的调用地址,如:

12842279-36e93c5ed62c11ce
image

2.通讯行为——触发:能被原生监听并捕获截拦的HTML5行为,都可以作为原生通讯协议的触发行为。

Hybrid H5的这类行为有console.log、alert、confirm、prompt、location.href等。将原生协议内容通过其中的某一行为触发,即可被原生正确捕获并解析。如:

12842279-cac89dfd16318b01.gif
image.gif

HTML5调用后,原生终端会捕获到内容:jsbridge://method?a=2&b=3#h5MethodTag

3.通讯行为——调用:原生终端根据HTML5传过来的内容,解析匹配后会路由到具体处理方法,执行原生能力逻辑。以iOS 为例(Swift语言),“调用”逻辑如下:

12842279-1791a931f411ec51
image

终端根据捕获到的协议内容,进行解析获取,若伪协议为原生指定的伪协议(“jsbridge”),就会根据method内容和query参数进行路由操作,寻找具体的方法执行逻辑。否则,忽略处理,按照webview原有跳转逻辑处理。以第2步触发的伪协议内容为例,在本例“调用”代码中被原生捕获后,会路由执行逻辑:self.method();

4.通讯行为——回调:原生根据HTML5传过来的内容,捕获JavaScript回调函数方法名,在原生逻辑执行结束后,将执行结果带到回调函数中并执行JavaScript回调函数。通过在第3步“调用”执行完后,iOS会调用JavaScript回调函数H5MethodTag:

12842279-9c390283d54c0dd7
image

通过以上4个关键点,即可做到HTML5与原生终端的相互通讯,完成HTML5对原生能力的调用。

▎****初次解耦:App内跨平台——创建JS API解耦通讯逻辑、封装平台差异

由上述通讯原理了解到,Hybrid H5直接调用定义好的原生通讯协议,即可完成通讯全过程。但这里有一个明显的问题,即Hybrid H5会强耦合于当前平台。不说跨App了,App内跨平台(Android、iOS、WP)都会显示吃力。这里面有很多原因,其中一个较明显的原因在于,不同平台App开发团队通讯协议规范定义存在不一致。再者,HTML5业务代码上满满的类似 JSONP的协议调用,也并不好维护。

要达到Hybrid H5在App内跨平台,业界常见做法是App对外提供JS API。通过JS API将各平台协议规范差异进行封装,解耦通讯逻辑,并以函数接口的方式提供给Hybrid H5调用。JS API接口一般会定义成如下格式:

12842279-a750a8a3340d1859
image
12842279-5d78a91df53eb717
image

通过JS API实现Hybrid H5在App内跨平台的原理图

原理核心:HTML5与原生通讯之间增加一层JS API,JS API完成三大行为:API接口创建、协议URL组装、创建iframe发起伪协议请求。

下面会以手Q JS API中的核心源码进行分析。

1.API接口创建:JavaScript函数接口封装、平台差异处理,方便HTML5函数调用。

12842279-e33d226fcc750f69
image

mqq.build方法为API接口创建方法。通过传入待创建的JS API方法名(mqq.tenpay.openTenpayView)和不同平台(Android、iOS)的差异处理配置。最终会生成HTML5可调用方法:

12842279-fdd96be01236a9f1
image

2.协议URL组装:从接口到URL协议的转换、回调处理,完成协议URL创建。

第1步中,不同平台差异处理都会调用mqq.invokeClient方法,该方法实际处理的就是原理图中与原生通讯的过程。我们先来看协议URL组装的过程。

12842279-d211e75c1ea526e2
image

协议URL组装的过程实际上是对传入参数按协议规范进行拼串的过程,其中包括匿名回调函数的回调索引创建、协议名&协议路径拼串、传参循环遍历拼串。

3.创建iframe发起伪协议请求:请求触发。

12842279-cab6638c989acad1
image

通过创建iframe来完成协议调用,并在调用结束后将iframe删除,即可在不影响原HTML5流程的情况下完成调用全过程。

▎****再次解耦:App间跨平台——JS API细化,封装App差异

通过上述的解耦处理,Hybrid H5已经可以在App内各平台运行了。但往往这种JS API是App级提供的JS API(下面简称App JS API),App JS API并不会去兼容别的App的差异。而实际情况具体到某一Hybrid H5,尤其是与App外部合作的Hybrid H5,则并不仅仅只运行在一个App上。比如信用卡还款业务,微信有,手Q 也有,功能都一样。这种情况就需要进一步的解耦,从业务侧再抽离一层JS API(下面简称 H5 JS API)来处理App间的差异,而非每个App各自一套HTML5。

12842279-d087ad8dc6dc362e
image

利用从业务侧抽离出的H5 JS API来处理App间的差异,原理示意图

原理核心:Hybrid H5业务上增加多一层自维护的 H5 JS API,H5 JS API完成两大行为:App JS API差异请求、App JS API差异封装。

1.App JS API差异请求:根据当前运行环境App请求具体的App JS API。

下面以Hybrid H5需同时运行在手Q和空间独立版的App JS API差异请求处理逻辑。

12842279-8482288cd1fd0f45
image

除了对需兼容的App进行差异请求外,还应对在不兼容的App运行时做跳转到主兼容App打开当前页面的逻辑处理,并做引导性提示,保障页面的完整可用性。

2.App JS API差异封装:根据当前具体运行的平台调用相应的App JS API 接口。H5 JS API的接口形式尽量与主运行App的JS API保持一致

下面以打开QQ钱包原生页和原生页面跳转能力为例,做App JS API的差异封装。

12842279-a0c5016c8feab1ca
image

调用openTenpayView,页面能在手Q中正常调用,而在非手Q时则跳转回手Q打开处理;

调用openUrl,对于手Q和空间独立版做相应的接口调用,而其他平台则直接使用HTML5的 location 跳转。

▎****总结

HTML5本质是具有跨平台性的。Hybrid H5因混合了原生能力,强耦合于原生,不再具有跨平台性。要恢复其跨平台能力,关键在解耦,将其耦合于原生的部分解耦封装起来。

解耦是开发很重要的一项能力,Hybrid H5跨平台性的回归正得益于解耦的处理。

因耦合而导致某项能力减弱的情况还有很多,比如HTML5的灵活性等等。遇到这种情况各位开发者不妨也试试解耦,或许会有意想不到的收获喔~

猜你喜欢

转载自blog.csdn.net/weixin_34301307/article/details/87499323