JSbridge的设计(一)API注入方式

538 阅读3分钟

前言

大家好,我是抹茶。
在Hybrid APP中,H5和Native需要相互配合,最终实现整个流程的闭环,在这两者中间起到桥梁作用的就是JSBridge。

在比较流行的JSBridge中,主要是通过API注入拦截URL请求来达到native端和webview端相互通信的效果的。

本文将介绍API注入方式。

如下图所示,Native原生(Android或ios)会将JSBridge注入到window全局对象上。
H5会通过形如window.JSBridge.functionName(name,data,callback)的方式调用原生的api。

作用.png

整体流程图

我们梳理一下整个的通信流程,如下图所示

流程.png

结合这个流程,我们需要思考以下问题:

  1. Native如何向H5注入JSBridge
  2. H5如何调用原生的API
  3. Native如何得知H5调用了哪些api,传递了哪些信息?
  4. Native如何将结果通知H5

我们一个一个问题的解决过去。

具体步骤

1. Native如何向H5注入JSBridge?

首先,Hybird H5是运行在原生应用内嵌浏览器控件WebView中的,Android是WebView,IOS是UIWebViewWKWebView

以Android为例,要实现javascript可以调用Android方法,在webView容器中注入一个Java代理。

// 安卓侧代码
    class JavaProxy{
        @JavascriptInterface //注意这里的注解。出于安全的考虑,4.2 之后强制要求,不然无法从 Javascript 中发起调用
        public void javaFn(){
            //xxxxxx
        };
    }

    webView.addJavascriptInterface(new JavaProxy();, "JSBridge");

这样就在webView容器中的全局作用域,增加了一个JSBridge属性,也就是拥有了window.JSBridge对象。

2. H5如何调用原生的API?

在javascript中,可以通过JSBridge.javaFn()调用Java侧的方法。

// H5侧代码
JSBridge.javaFn()

Android可以在JSBridge身上注入更多的方法,如下

// 安卓侧代码
javaProxy.register("getPackageName", new JavaHandler(){ 
    @Override 
    public void handle(String message, final ValueCallback<String> callback){ 
        //xxxxx 
    } 
})

然后,H5就可以通过JSBridge.getPackageName调用最新注册的方法了。

3. Native如何得知H5调用了哪些api,传递了哪些信息?

如上面的流程,可以通过具体的函数名得知是调用了哪个函数,传递的信息可以通过函数参数的方式实现。

4. Native如何将结果通知H5?

// 安卓侧代码
// 供javascript调用的接口
javaProxy.register("getPackageName", new JavaHandler(){ 
    @Override 
    public void handle(String message, final ValueCallback<String> callback){ 
        // 处理从 JavaScript 传递过来的参数
            System.out.println("Received message from JavaScript: " + message);

            // 调用 JavaScript 的回调函数并传递参数
            webView.post(() -> { 
                // 在webView容器里执行JS代码,执行相应的回调函数
                webView.evaluateJavascript("javascript:callback('" + response + "')", null);
            });
    } 
})

可以看到通过webView.evaluateJavascript("javascript:callback('" + response + "')")可以执行javascript侧的代码,从而实现js侧的回调函数被执行。 这样,API注入的整体流程就完成了。

url拦截的方式见文章JSBridge原理解析——以WebviewJavascriptBridge实现方式为例,本来想自己写一些这部分,但是这文章真的很系统了,比我研究深入。

总结

JSbridge的本质是通过webView容器向window全局对象上注入一些数据的方法,通过调用这些方法,native侧可以感知到,通过执行javascript的回调函数,使H5侧收到数据。

参考文档

如何写一个JSbridge

JSbridge的原理

bridge原理解析