Hybrid框架总结 - Hybrid SDK 架构设计 (二)
😄

Hybrid框架总结 - Hybrid SDK 架构设计 (二)

一、前言:

我们还是通过WebView UI为基础方案来进行设计的。如:微信的JS-SDK,通过JSBridge完成H5与Native的双向通讯,从而赋予H5一定程度的原生能力.
以下为图介绍:
notion image
由于现状的JSBridge 存在多套 HybridAPI协议,及多套WebView的引用。我们不得不重新进行梳理。
通过梳理后:
 

二、方案

我们也基于以上的问题,同时结合了调研资料设计出一套相对更为完善的Hybrid架构。其中主要包含了:
  1. 协议标准化设定
  1. 通用桥的设定.
  1. 性能提升的关键:离线.
 
大致框架会变为:
notion image
 

三、通信协议

3.1 首先我们需要介绍一下,本次采用的通信方式:

采用JSBridge 注入方式,其中包含一个JSBridge对象挂载至window上,并提供js2native、native2js两个核心方法.

native与js 通信流程:

 
notion image
 

js通信流程:

 
notion image
 

聊一聊 js2native、native2js两者方法的协议标准:

首先js2native请求结构了:(_js2native Function)
message {
	handleName: toast,
	callbackId: id,
	data: json
} 
其次介绍 native2js请求结构: (_native2js Function)
message: {
   callbackId : id,
	 responseData : {
			errorCode: code,
			errorMessage: string,
			data: json。
		}
}
以上两个json结构为bridge中的主要的通信结构体.
 
但如果要保证这两个方法的正常执行,前提是我们需要保证WebView在加载完成H5页面过程中需要将该脚本进行注入。(将JsBridge挂载至Window上)
如何保证呢?

3.2 保证JsBridge对象成功挂载至H5.window上:

 
  1. 首先我们同需要确认将离线的脚本布置放入固定的位置,如:assets之中.
  1. 及确认注册的应该在什么时机更为合适.
 
WebView 从创建到渲染成页面流程:
notion image
 
然而我们的JsBridge对象被使用的时机则当执行JavaScript之前:(这个时候需要确保JsBridge的注入成功.
 
由于初始化过程我们无需监听,我们只通过设置WebViewClient、WebChromeClient两个对象来监听整个WebView创建的流程,而它们主要分为几个核心生命周期:(单URL,如存在重定向相关则重新定义)
  • WebViewClient.onPageStarted 回调: 代表WebView开始执行loadUrl函数.
  • WebChromeClient.OnProgressChanged 回调:代表WebView 加载进度.
  • WebViewClient.onPageFinished 回调:代表WebView 加载完成.
  • WebChromeClient.onJsPrompt 回调:为注入方案
 
以下为我们以onPageStarted 会注入起始,onProcessChanged为过程重复注入策略,onPageFinished为最终兜底处理注入方案.
已经采用在最后window.jsBridge注入成功后,执行dispatchEvent方法发送readyEvent事件
function dispatchReadyEvent() {
        try {
            var readyEvent = document.createEvent('Events');
            readyEvent.initEvent('WebViewJavascriptBridgeReady');
            readyEvent.bridge = WebViewJavascriptBridge;
            var tujiaJSBridgeEvent;
            if (document.createEvent) {
                tujiaJSBridgeEvent = document.createEvent("CustomEvent");
                tujiaJSBridgeEvent.initCustomEvent("TujiaBridgeReady", true, false, {
                    bridge: TujiaJSBridge
                })
            } else {
                tujiaJSBridgeEvent = new CustomEvent("TujiaBridgeReady", {
                    detail: {
                        bridge: TujiaJSBridge
                    },
                    bubbles: true,
                    cancelable: false
                })
            }
            document.dispatchEvent(readyEvent);
            document.dispatchEvent(tujiaJSBridgeEvent)
        } catch (e) {}
    }