JsBridge原理分析

看了这个Github代码 https://github.com/lzyzsd/JsBridge,想起N年前比较火的Hybrid方案,想看看现在跨平台调用实现有什么新的实现方式。代码看下来之后发现确实有点独特之处,这里先把核心的思想抛出,然后在细化Native (Java)如何调JS以及JS如何调Native (Java)。

Native与JS相互调用使用的最核心的思路是:

1、Native通过WebView的loadUrl调用JS的code;

2、JS通过设置URL跳转触发WebViewClient的shouldOverrideUrlLoading通知Native有数据发生;

当然这只是核心思路,实际上还涉及到一些细节,其中比较重要的就是scheme的设计,双方都是通过这个scheme来约定方法和返回数据。可以参考BridgeUtils的YY_RETURN_DATA和YY_FETCH_QUEUE。当然还有方法名的约定;以及交换数据格式的约定(JSON)。

一、Native(Java)调JS

在Native调JS之前,需要现在JS中注册handler,也就是方法名与方法体, 参考Github README:

WebViewJavascriptBridge.registerHandler("functionInJs", function(data, responseCallback) {
        document.getElementById("show").innerHTML = ("data from Java: = " + data);
        var responseData = "Javascript Says Right back aka!";
        responseCallback(responseData);
    });

Native调用JS

webView.callHandler("functionInJs", new Gson().toJson(user), new CallBackFunction() {
        @Override
        public void onCallBack(String data) {

        }
    });

需要传递之前约定的方法名,方法参数(json格式)以及一个JS执行结果返回的callbackFunction。

1、JS注册自己对外开放的接口,用于被Native调用;

2、外部调用BridgeWebView的callHanlder方法调用js接口,传递的参数为约定的方法名,json格式的参数以及一个callback,这个callback用于接收js接口返回的结果;

3、callHandler调用内部的doSend方法,doSend方法中构造一个message,这个message中包含方法名,参数json内容以及一个新构造的callbackId,这个id还用于接收js返回结果的callback的key,保存到map中用于后续查找对应的callback;然后会调用queueMessage进行分发;

4、queueMessage主要是调用dispatchMessage进行处理;

5、dispatchMessage中构造一个url用于进行js调用,这个url是“WebViewJavascriptBridge._handleMessageFromNative('message的json格式');”,

6、通过loadUrl触发js的接口被调用;

7、触发JsBridge中的_handleMessageFromNative被调用;

8、调用_dispatchMessageFromNative进行message消息的处理,

9、_dispatchMessageFromNative中,根据message的json,找到handler name并找到1中注册的handler,然后调用handler处理message中包含的data;在handler执行之前,构造了一个responseCallback,这个responseCallback在handler执行之后会被执行,

_doSend({
    responseId: callbackResponseId,
    responseData: responseData
});

10、_doSend中,这个json内容被放进一个queue中留作后用(主要是用于后续被Native请求得到),暂时不会直接返回,这个responseId就是之前传递过来的message中的callbackId;

var callbackResponseId = message.callbackId;

11、通过重定向url,触发BridgeWebViewClient的shouldOverrideUrlLoading;

12、在shouldOverrideUrlLoading中,会根据url的前缀判断调用webview中的哪个方法,这里调用的是flushMessageQueue;

13、flushMessageQueue中做的事情比较绕圈子,它首先构造了一个新的responseCallback,在这个responseCallback中封装了针对之前注册的callback的调用,之后,这个responseCallback作为方法‘return’的value存进map中,用于后续handlerReturnData中被处理;

14、通过loadUrl(‘WebViewJavascriptBridge._fetchQueue();’)触发JsBridge的_fetchQueue;

this.loadUrl(jsUrl);
      // 添加至 Map<String, CallBackFunction>
responseCallbacks.put(BridgeUtil.parseFunctionName(jsUrl), returnCallback);

这里jsUrl就是‘WebViewJavascriptBridge._fetchQueue();’

15、在jsBridge中的_fetchQueue函数中,把10中保存的queue中的json数据转换成json string,作为url的一部分进行跳转

function _fetchQueue() {
    var messageQueueString = JSON.stringify(sendMessageQueue);
    sendMessageQueue = [];
    //android can't read directly the return data, so we can reload iframe src to communicate with java
    bizMessagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}

这会导致BridgeWebViewClient的shouldOverrideUrlLoading被触发;

16、在BridgeWebViewClient的shouldOverrideUrlLoading中,这回根据url前缀,判断需要调用BridgeWebView的

webView.handlerReturnData(url);

17、在BridgeWebView的handlerReturnData中,

void handlerReturnData(String url) {
   String functionName = BridgeUtil.getFunctionFromReturnUrl(url);
   CallBackFunction f = responseCallbacks.get(functionName);
   String data = BridgeUtil.getDataFromReturnUrl(url);
   if (f != null) {
      f.onCallBack(data);
      responseCallbacks.remove(functionName);
      return;
   }
}

根据url找到对应的方法就是13中的‘return’以及它对应的callbackFunction,也是13中对callbackId对应的callback进行封装的callback,然后提取出15中的json data,回调callback。在onCallBack中,会找到json中的callbackId以及js执行的结果data,然后用callbackid对应的callback调用data完成js执行结果的处理。

至此,从Native调用JS以及处理JS调用返回内容的流程完毕。至于JS调用Native的流程跟这个类似,可以根据源码进行还原。总之还是开头总结的:

Native与JS相互调用使用的最核心的思路是:

1、Native通过WebView的loadUrl调用JS的code;

2、JS通过设置URL跳转触发WebViewClient的shouldOverrideUrlLoading通知Native有数据发生;

转载于:https://my.oschina.net/kingguary/blog/1833718

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值