初探JSBridge

论坛 期权论坛 期权     
方凳雅集   2019-7-29 01:09   2339   0


作者 | 镜逸


Hybrid、React Native和weex等方案都需要Android和IOS端提供原生能力的支持,它们获取原生能力都是通过JSBridge来实现的,本文通过一个Android端JSBridge来讲解其原理。
[h2]前言[/h2]有段时间没写文章了,最近在写rax的时候,需要实现一个分享功能,对于前端而言只需要调一下native(IOS和Android)提供的API就好了。虽然实现这个功能很简单,但有没有想过native是如何提供API给前端调用的呢,答案就是我们今天要聊的JSBridge,如果你写过hybrid、react native、weex或rax,相信你或多或少听过这个东西。即使没有听过也没关系,下面会初步的介绍一下它。
[h2]JSBridge[/h2]现在开发移动端应用,供我们选择的方案有很多, 比如native(IOS和Android)、 hybrid和react native等。其中hybrid、react native等方案对前端很友好,毕竟是用我们熟悉的JavaScript开发,但JavaScript无法直接调用native本身提供的能力,比如获取相册信息。所以就需要通过一种方式将native能力提供给JavaScript,同时native也可能需要调用JavaScript的一些功能,而JSBridge就是JavaScript和native之间的桥梁,提供两者相互调用的能力。



[h2]简单例子[/h2]JSBridge的实现方式有很多,有通过C++实现的,也有通过native提供的webview实现的。这里我们重点理解原理,通过native提供的webview实现比较简单,另外相较于IOS,我对Android更熟悉一点,所以接下来将通过一个Android端的JSBridge来讲解,这个代码是我在GitHub上面找的,具体见:https://github.com/lzyzsd/JsBridge。

native端注册函数供JavaScript调用:




上面代码是Android端注册了一个名为submitFromWeb的函数供JavaScript端调用,其中handler函数是具体执行的内容,String类型的data是JavaScript端调用时传过来的参数,CallBackFunction类型的function是用来将执行的结果回传给JavaScript。

JavaScript调用native端提供的函数:




上面代码是JavaScript通过提前注入的WebViewJavascriptBridge对象调用native端提供的submitFromWeb函数,传递的参数为{'param': str},调用结束后会回调callback函数。
[h2]原理解释[/h2]


整个调用流程如上图所示,Android端调用registerHandler,将submitForWeb函数保存在函数池中。JavaScript调用callHandler函数,首先将回调函数callback保存在回调函数池中,同时会生成“调用Message”,然后通过一定的方式将该Message传递给Android端;Android端根据传过来的Message判断调用什么函数,并在函数池中寻找,找到了就执行,执行完之后会生成一个“响应Message”,该Message中包含回调函数的标识和函数执行的结果;之后通过一定的方式将该Message传递给Javascript端,JavaScript端收到Message后,从回调函数池中找到回调函数并执行。

这里需要了解2个点,JavaScript是如何将Message传递给Android端的,Android端是如何将Message传递给JavaScript的。

1. JavaScript传递Message到Android:

JavaScript将Message传递给Android端是通过WebviewClient中shouldOverrideUrlLoading来实现的,webview中iframe的src如果发生变化,就会调用该函数。首先将Message json化,将其放到iframe src属性的url上(类似http中get请求),WebviewClient感受到iframe src发生变化,就会调用shouldOverrideUrlLoading函数,拿到url解析获取Message。WebviewClient的shouldOverrideUrlLoading具体用法请见:https://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,%20java.lang.String)

2. Android传递Message到JavaScript:

Android端将Message传递给JavaScript是通过webview.loadUrl('XXXX(args)')来实现的,其中XXX是JavaScript环境中的提前设置的一个方法,args表示需要传递的参数。这里是不是很眼熟呀,没错,这里的实现和jsonp是不是很像。

上面只是简单的介绍了JavaScript调用Android注册的函数,相反Android也可以调用JavaScript注册的函数,原理和上面类似,所以这里就不再赘述。
[h2]总结[/h2]本文在没有涉及代码的情况化,粗略介绍了一下JSBridge的原理,忽略了很多技术细节,比如自定义的Webview是如何实现的;JavaScript端将Message传递给Android端详细的url格式;Android端将Message传递给JavaScript端时调用的函数(提前注入的);JavaScript端是如何提前注入信息的,比如WebViewJavascriptBridge这个对象。如果你想了解这些技术细节的话,可以去看一下源码:https://github.com/lzyzsd/JsBridge。

接下来我会写几篇关于React Fiber相关的文章,如果您对此感兴趣,欢迎通过下面的二维码关注一下我们阿里巴巴新零售CBU技术部前端的公众号,这样您就能在第一时间阅读到下篇文章了。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP