JsBridge介绍

JsBridge

什么是JsBridge呢?通俗的说就是当我们在app中开发页面时,app和h5界面交互时需要用到的函数。

目前实现js和app通信的方式有很多,这里我们简单的说一说(下面例子都以android举例)

JavaScriptInterface

这是Android4.2提供的官方解决方案,通过addJavascriptInterface在浏览器的window对象中注入一个方法,例子如下。

webView.addJavascriptInterface(new JsInterface(), "WebViewInterface");

public class JsInterface {

        @JavascriptInterface
        public void openActivity(String activityClazz) {
            // open activity
        }
    }
try {
    window.WebViewInterface.openActivity('xxxx');
} catch (e) {}

用户通过执行上述代码即可打开一个activity

onJsPrompt

js中有alert,prompt,console,webview中提供了对应了的方法去监听这些js函数触发。js和app之间可以通过制定合理的协议来传输对应的数据。这些方法中alert, console的使用频率较高,而prompt是唯一一个自定义返回值,因此,一般都会使用它来做简单的同步交互。

参考库safe-java-js-webview-bridge

url scheme

url scheme是一种由app提前注册在app中,可以直接调用app功能的类似于url的链接,他的格式大致是这样的schem://action?params=12。这些scheme必须是由app提前注册的,且不能重复,比如微信的scheme是以weixin://开头的。相信有做过app下载页的同学应该会用过这个功能。比如,产品提的需求是跳到下载页时,先判断用户有没有装app,有装的话直接打开app,没有则继续下载。这应该是url scheme的最佳的使用场景。

if (/(iPhone|iPod|iPad)/i.test(ua)) {
    location.href = iosDownloadUrl;
} else if (/android/i.test(ua)) {
    var iframe = document.createElement('iframe');
    iframe.src = scheme;
    iframe.style.display = 'none';
    iframe.style.width = '1px';
    iframe.style.height = '1px';
    document.body.appendChild(iframe);

    if (/android.+chrome/ig.test(ua)) {
        var script = document.createElement('script');
        script.src = scheme;
        document.body.appendChild(script);
    }

    setTimeout(function(){
        location.href = androidDownloadUrl;
    }, 1000);
} else {
    location.href = androidDownloadUrl;
}

通过上面的代码,其实我们可以发现url scheme有一个好处就是android和ios是通用的。android通过shouldOverrideUrlLoading,ios通过delegate来拦截url请求,他们只需要对拦截的url分析看看是否符合我们之前注册好的协议在做后续的判断。

我司使用的两套JsBridge库都是用这种方式来实现的:

这里我们主要讲一下lzyzsd/JsBridge这个库。

  1. 重写shouldOverrideUrlLaoding方法,根据协议头不同做不同处理。
  2. onPageFinished判断是否注入了js,没有则注入。(这里个人在使用时,感觉有点问题,通过onPageFinised方法注入可能导致注入时间很晚)
  3. 加载完成后,可以通过callHandlerregisterHandler方法来完成JsBridge的注册和调用。
  4. registerHanndler是直接在messageHandlers中添加一个函数
  5. callHandler则是生成一个请求消息,并把这个消息推送到队列中。如果队列中信息为空,则webview会通过执行loadUrl(jsCommand)的方式去执行js中注册的方法

大致流程就是这样,这篇语句不通的文章就到这里了。最近一直在搞JsBridge的开发,一直没整明白JsBridge到底是怎么实现的,于是就有这篇介绍性的文章。总结一下,就是urlScheme来实现一个只有你和客户端懂得协议。