LightWebviewBridge-原理篇
介绍
LightWebviewBridge
定位为一个轻量级、小而美的Hybrid混合APP解决方案工具,帮助开发者快速实现H5APP或内嵌H5界面功能,只聚焦于业务功能开发,而不用关注H5和Native的通信实现,便可快速实现相应业务功能,达到类似小程序、公众号
的效果;
效果
<>
图解
先上一张功能流程图熟悉一下:
上图是一个从H5端到Native端的完整功能流程图,形成了一个完整的闭环链。其中底层(LightWeviewBridge)是已经封装好的通信引擎,业务侧无需关注,只需要关注上面业务侧的功能实现。
左边是H5端,H5端通过调用API callNative方法,发出请求Request调用Native功能,同时会注册一个回调函数,之后会回调Native端返回的数据。
右边是Native端,接受到H5端的请求后,会从配置文件bridgeConfig中获取匹配的功能,
执行原生能力,之后会将数据返回给H5端的回调函数。至此,整个功能闭环执行完成。
原理
实现JS调用Native很简单,但是如果要进一步实现JS与Native闭环互通、异步回调、JS与Native的调用标准化、统一入口等需求,就得将技术点逐个攻克。
-
JS调用Native
在Android侧有3种方案:
一,通过@JavascriptInterface新增原生对象映射到JS;
二,通过WebViewClient的shouldOverrideUrlLoading()方法回调拦截url,通过自定义协议头在原生中实现。
三,通过WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt()方法,对消息message进行拦截。
LightWeviewBridge采用的第一种方案。
-
Native调用JS
通过Webview执行js,有2种
一,webview.loadUrl()
二,webview.evaluateJavascript()
LightWeviewBridge采用的混合方案。
-
数据如何实现闭环传输
通过约定请求体Request和返回体Response对象的数据格式,在请求和回调时分别将数据作为成员变量放入其中,在节点流程中进行绑定,帮助数据闭环流转到正确节点。
-
异步回调
因为JS和Java的运行环境不同,浏览器UI端JS是单线程顺序执行,而Java后台功能可多线程异步执行,所以请求与回调需要考虑异步设计。
-
统一标准化引擎
如果只考虑实现,在开发中,每一个业务都需要将以上技术重复实现一遍,所以
通信引擎的设计很有必要,将端到端到出入口及数据格式标准化、统一化,帮助开发 者只关注业务功能。
代码解析
核心
-
WebViewBridge:JS调用Native的入口对象。
callFunc(…):暴露给JS的调用入口方法。
call(…):调用原生功能的统一入口方法。
-
NativeFunc:业务原生功能基础类,负责持有通信框架上下文对象,JS回调相关等。
-
IWebViewDataHandler:负责JS回调的接口,一般交给Webview实现。
配置
- BridgeConfig:JS端到Native功能的映射配置。
模型
- Request:JS到Native的请求体,3元素:funcID(功能唯一ID值,必填)、data(传入数据,可选)、callbackKey(回调函数ID,可选)
- Response:Native到JS的返回体,callbackKey(回调函数ID),data:(返回数据)
上下文
- BridgeContext:持有Android上下文Activity和ActivityStarter,作为Native与JS界面交互功能的中间人。
- ActivityStarter:作为进阶调用另外Activity或Fragment的接口,提供给原生功能使用。
Bridge.js
- callToNative(…):JS API,调用原生能力,传入参数为Request3元素。
- callbackFromNative(…):回调函数,供Native端调用。
- callbacks:回调Map,保存对应回调函数key和回调函数,实现JS端异步调用,以空间换时间。
后记
LightWebviewBridge就是一个轻量级的JSBridge框架,它的出现是为了帮助那些不用集成大框架,也不想从0开始写通信实现,而且又希望将这一模块单独解耦拿出来的开发者们。
如果反响不错,得到了大家关注、建议,或更多场景解决需求,也欢迎大家积极反馈参与👏🏻,后续会有迭代更新。GitHub|码云
毕竟,一人拾火难起灶,众人抱薪方得暖🔥