JsBridge交互原理以及二次开发

JsBridge原理以及二次开发
摘要由CSDN通过智能技术生成

JsBridge原理以及二次开发

1丶JsBridge原理

1.1丶JS交互的简单使用

  • 🏷原生方式

    • Native调用Web:

      方式1:Android4.2以前

       webView.loadUrl(jsMethod);
      

      方式2:Android4.2以后:新增

       webView.evaluateJavascript(jsMethod, new ValueCallback<String>() {
             
                  @Override
                  public void onReceiveValue(String s) {
             
                      Log.d(TAG, "nativeCallH5ByPrimary2  onReceiveValue: "+s);
                  }
              });
      

      两种方式对比:

      调用方式 版本支持 是否刷新页面 是否存在回调 是否可获取常量信息
      loadUrl Android各版本
      evaluateJavascript Android4.2及以上
    • Web调用Native:Native提供JavaScript交互的对象

      **方式1:**调用Native挂载在window上的对象进行调用

      Native添加JavaScript

      webView.addJavascriptInterface(new JSHelper(), "jsHelper");
      

      web调用Native方法

      window.jsHelper.webCallNativeFunc();
      

      方式2:Web端调用location.href的方式调用(需要Native进行拦截相应的url进行处理)**

      location.href='xxxxx'
      

      方式3:Web端创建iframe标签,通过iframe.src方式调用(需要Native进行拦截相应的url进行处理)**

      iframe.src='xxxxx'
      

      三种种方式对比:

      调用方式 是否刷新页面 是否存在回调 其他
      window.jsHelper 具体看Native方法 需Native创建js交互对象,并挂载在window上
      location.href 需要Native进行拦截相应的url进行处理;连续多次调用只执行最后一次
      iframe.src 需要Native进行拦截相应的url进行处理;
  • 🏷JsBridge

    • Native调用Web

      //functionInJs该方法需Web端注册
      webView.callHandler("functionInJs", "TEST BRIDGE", new JsCallBack() {
             
          @Override
          public void callBack(String result) {
             
              Log.e(TAG, "repsonseData from web, data = : "+result );
          }
      });
      //or
       webView.sendMessage("functionInJs", "TEST BRIDGE", new JsCallBack() {
             
                          @Override
                          public void callBack(String data) {
             
                               Log.e(TAG, "repsonseData from web, data = : "+result );
                          }
                      });
      
      
    • Web调用Native

      // functionInNative该方法需Native端注册
      window.WebViewJavascriptBridge.callHandler(
          'functionInNative'
          , params
          , function(responseData) {
             
              console.log("repsonseData from java, data = " + responseData);
          }
      );
      

1.2丶JsBridge交互方式和原生交互方式对比

交互方式 调用链路 交互方法 优点 缺点
原生交互 NativeCallH5 laodurl 版本支持Android4.2以下,兼容较好 1.会刷新页面
2.无返回值
3.js属性值无法获取
evaluateJavascript 支持Web返回值 1.返回值是否存在由js方法决定
H5CallNative window对象 结果同步返回 1.需Native声明js交互对象并挂载到Window上
location.href 调用方便 1.无返回值且需要Native针对URL进行拦截处理
2.连续多次调用只执行最后一次
iframe.src 独立窗口处理js交互 1.无返回值且需要Native针对URL进行拦截处理
JsBridge交互 NativeCallH5 sendMessage 1.版本兼容良好
2.均存在返回值
3.调用方式简单
1.需要Native针对URL进行拦截处理
2.需Web注入jsbridge.js
3.交互方法需接收端进行注册
callHandler
H5CallNative

1.3丶JsBridge原理

js关键方法

Web端注册方法

// Web端注册方法
bridge.registerHandler("messageName", function(params, responseCallback) {
   
    if (responseCallback) {
   
   		// Web端给Native的结果回调
        responseCallback(responseData);
    }
});

JsBridge.js中的方法

registerHandler方法负责注册native调用Web的方法

// 注册native调用Web的方法
function registerHandler(messageName, handler) {
   
    messageHandlers[messageName] = handler;
}
// 保存web端当前页面的js交互的处理类,通过messageName进行保存和获取
var messageHandlers = {
   };

callHandler方法,用于Web调用Native的关键方法,其内部调用了_send方法

function callHandler(messageName, data, responseCallback) {
   
    _doSend({
   
        messageName: messageName,
        data: data
    }, responseCallback);
}

_doSend 方法用于Web端发送消息给Native侧,同时保存相应的回调对象,回调对象用于后面接收处理Native的回调结果

function _doSend(message, responseCallback) {
   
    console.log("调用链路: "+" _doSend message="+JSON.stringify(message));
    // 判断当前的responseCallback对象是否为空,该判断的作用是用于区分是Web端调用Native方法,还是Web主动通知Native去刷新消息队列
    if (responseCallback) {
   
        var callbackId = 'H5CallNative_cb_' + (uniqueId++) + '_' + new Date().getTime();
        // web保存调用Native方法时的回调对象,最后会在_dispatchMessageFromNative分发处理Native发送过来的消息时取出,并返回
        responseCallbacks[callbackId] = responseCallback;
        message.callbackId = callbackId;
    }
	// 保存Web端发送的消息信息
    sendMessageQueue.push(message);
    // iframe.src主动发送请求通知Native,该uri最终会执行到WebViewCilent中的shouldOverrideUrlLoading方法
    messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}

_fetchQueue 方法,web侧提供给Native调用的方法,用于刷新消息队列信息,并把消息结果返回给Native

// 提供给native调用,该函数作用:获取sendMessageQueue中的数据返回给native,因为android不能直接获取返回的内容,因此使用url shouldOverrideUrlLoading 的方式返回内容
function _fetchQueue() {
   
    // 取出所有的发送消息的信息内容
    var messageQueueString = JSON.stringify(sendMessageQueue);
    console.log("调用链路: "+" _fetchQueue messageQueueString="+messageQueueString);
    // 置空消息队列
    sendMessageQueue = [];
    //android无法直接读取返回数据,因此我们可以重新加载iframe src以与java通信
    messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}

_handleMessageFromNative方法,用于Web侧处理native发送过来的消息

function _handleMessageFromNative(messageJSON) {
   
    console.log("调用链路: "+" _handleMessageFromNative messageJSON="+messageJSON);
    console.log("调用链路: "+" _handleMessageFromNative bool="+(receiveMessageQueue && receiveMessageQueue.length > 0));
    //页面加载完成时会清空消息队列,因此当重新初始化的时候,会把当前页面的js交互消息进行保存
    if (receiveMessageQueue && receiveMessageQueue.length > 0) {
   
        receiveMessageQueue.push(messageJSON);
    } else {
   
        // 分发处理Native发送过来的消息
        _dispatchMessageFromNative(messageJSON);
    }
}

_dispatchMessageFromNative 方法,分发处理Native发送过来的消息

function _dispatchMessageFromNative(messageJSON) {
   
    setTimeout(function() {
   
        var message = JSON.parse(messageJSON);
        var responseCallback;
        // Web调用native完成后,js获取结果的回调函数,
        if (message.responseId) {
   
            // 从responseCallbacks集合中取出结果回调,该回调是在web调用_doSend方法时进行保存的
            responseCallback = responseCallbacks[message.responseId];
            if (!responseCallback) {
   
                return;
            }
            responseCallback(message.responseData);
            // 从responseCallbacks集合中移除结果回调
            delete responseCallbacks[message.responseId];
        } else {
   
            // native主动调用Web方法,发送的消息
            if (message.callbackId) {
   
                var callbackResponseId = message.callbackId;
                responseCallback = function(responseData) {
   
                    // 当web处理native发送过来的消息结束后会调用该方法,发送消息给Native侧,通知已经处理好结果
                    _doSend({
   
                        responseId: callbackResponseId,
                        responseData: responseData
                    });
                };
            }

            var handler = WebViewJavascriptBridge._messageHandler;
            if (message.messageName) {
   
                // 取出处理Native调用web方法的处理函数对象,该对象是在Web端注册方法时进行保存的
                handler = messageHandlers[message.messageName];
            }
            //查找指定handler
            try {
   
                // 处理native发送过来的消息.该方法在Web端registerHandler注册方法中声明
                /**
                 *
                 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值