AndroidX技术栈之JSBridge通信原理
原理分析
两个方向
案例中有两个例子,一是通过左右摆动手机,失去平衡的球会左右滚动;另外一个是通过点击页面上的按钮“JS call Android Native function”,H5页面可以调用native的一个echo方法,并把echo的内容在H5页面中打印出来。
- 第一个,是native调用H5中的javascript方法
- 第二个,是javascript调用native的方法
native -> javascript
使用WebView.loadUrl(“JavaScript:function()”)即可。
javascript -> native
通道
webview有一个方法可以设置具体的client:setWebChromeClient,而WebChromeClient对象有3个方法:
- onJsAlert
- onJsConfirm
- onJsPromp
分别监听webview页面中的
- window.alert
- window.confirm
- window.prompt
因此,可以利用这3个事件,定制出一个H5到native的通道出来。那么对于这3个javascript事件,哪个最合适用来做我们的bridge通道呢?
比较这3个事件触发的javascript消息框,alert是最常被页面调用到的,因此不适合我们定制通道;其次,confirm在一些页面交互上也经常被用到,比如下载确认;而prompt几乎很少被页面使用。
因此,我们选择prompt来构建我们的bridge通道。
协议
既然设计到两个“节点”的通信,不管通道是建立在网络上的2个真实节点,还是我们当前研究目标里的同APK应用里的webviewH5页面和native方法,就需要协调一个通信协议出来,保证通信双方能够听懂对方的话。
我们的目的是完成h5页面的javascript调用native中的某个class的某个method(带参数),然后获得native方法调用返回。
因此,我们首先定义javascript->native协议如下,类似http url:
jsbridge://className:callbackAddress/methodName?jsonObj
- className就是native的目标类名
- methodName就是目标类里的目标方法名
- jsonObj,这里使用json字符串作为入参格式,path与parameter使用?连接
- callbackAddress是H5页面里的javascript callback方法位置,用于native调用返回值的返回
再次,我们定义native->H5的返回协议如下:
{
"code":500,
"msg":"method is not exist",
"result":null
}
调用流程
有了通道,有了协议,就可以做H5 js调用native方法的具体实现了,具体处理和消息流程如下:
- 应用初始化时,注册目标类中的全部可用方法
- webview H5页面点击按钮后
- 注册callback方法
- 注册callback地址
- 拼装协议url : jsbridge://className:callbackAddress/methodName?jsonObj
- 发起prompt事件
- WebChromeClient的onJsPrompt()监听到prompt事件
- 解析H5页面发过来的url
- 获取目标类名,目标方法名,调用参数
- 在注册的目标勒种查找方法并调用,同时定义native callback方法
- 调用结束后,在原生callback方法中组装返回值
- 通过WebView.loadUrl(“JavaScript:callback()”)调用H5的callback方法,返回返回值给H5
- H5页面完成callback调用后,清理callback地址池