BridgeWebview原理简略分析

BridgeWebview通过Java端和JS端的Map与消息队列实现交互。Java调用JS使用loadUrl,JS调用Java则通过url重定向触发shouldOverrideUrlLoading。两者信息传递封装成消息,通过对应关键字或回调ID执行相应处理逻辑。
摘要由CSDN通过智能技术生成
整体理解:
1.Java端和JS端各自维护着两个Map和一个消息队列。
    一个Map维护着 提供给对方直接调用的方法,键值对<“方法关键字”,BridgeHandler>;在registerHandler时添加。
    一个Map维护着 调用对方时自己提供的回调方法,键值对<Id, CallBackFuntion>; 在执行callhandler时,创建相应的Id, 并与CallbackFuction相关联存入HashMap。(在直接调用时,该ID被设置为Message的callBackId字段;在执行回调时,该ID被设置为Message的responseId字段。)
    (注:java中map存的是对象,Js中Map存的是函数。额,对Js了解有限,知之不深。)
    消息队列中存储着要发送给对方的消息。双方的要交互的信息都是封装成消息来进行交互的。
2.二者信息交互的方式就是获取对方的消息,并进行分发处理:
    其中,
    2.1 java向js传递消息,是通过loadUrl()来调用JS的 _dispatchMessageFromNative() 方法,然后进行消息分发处理逻辑:
      如果是Java直接调用Js函数,根据 Message中函数关键字,从Map中获取对应的函数来执行。
      如果是Java回调Js函数,根据 Message中回调函数的ID,从Map中获取对应的回调函数来执行。
    2.2 Js向Java传递消息,是通过url重定向,触发WebviewClicent的 shouldOverrideUrlLoading()方法进行消息分发处理:
              如果是JS直接调用Java方法,根据 Message中函数关键字,从Map中获取对应的BridgeHandler对象,执行其handler()方法。
      如果是JS回调Java方法,根据 Message中回调函数的ID,从Map中获取对应的CallBackFunction对象,执行其onCallBack()方法。


一、JS调用Java过程:
#1.Java方的方法注册:
registerHandler(“【方法关键字】”, 实际逻辑执行BridgeHandler对象);        HashMap把二者关联

BridgeHandler对象的
@Override
public void handler(String callbackId , String data , CallBackFunction function) {
    …...
}


#2.JS方的调用:
WebViewJavascriptBridge.JS中包含一些列相关的JS函数:
// Java方法名、传递的数据、回掉函数
function callHandler(handlerName, data, responseCallback) {
    console.log(arguments);
    _doSend({
        handlerName: handlerName,
        data: data
    }, responseCallback);
}

在_doSend函数中,会生成一个 callbackId ,用于标识回调函数。在Map中存储和关联。
所有数据:调用关键字、传递数据、回调函数Id值 都被封装到Message中。Message被放在消息队列中。
messagingIframe.src 值的修改应该类似于url重定向之类的吧,总之能触发WebviewClient的URL拦截方法shouldOverrideUrlLoading()方法。
而在约定中,封装的这个url字符串的含义,等同于说消息队列中有消息,快来取呀!
//sendMessage add message, 触发native处理 sendMessage
function _doSend(message, responseCallback) {
    if (responseCallback) {
        var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
        console.log(callbackId);
        responseCallbacks[callbackId] = responseCallback;
        message.callbackId = callbackId;
    }

    sendMessageQueue.push(message);
    messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}


shouldOverrideUrlLoading()中拦截并解析相应url,执行相应的判断逻辑分支,触发对应的逻辑链条:
    0.创建一个回调对象,放到一个map中。该回调对象封装了JS消息的处理逻辑。
    1.调用  能够取出JS消息队列中消息  的JS函数;
    2.该JS函数,把消息队列中的消息数据封装后,以自定义的URL格式写在URL中。通过URL重定向,再次触发WebviewClient中的shouldOverrideUrlLoading()方法。
    3.shouldOverrideUrlLoading()中拦截并解析相应URL,执行相应的逻辑分支:
            从步骤0中的map取出相应回调对象,执行JS消息的处理,逻辑循环取出各个消息,依次做处理:
                创建回调JS的CallBackFunction对象,它执行的相应逻辑是,把各个相关数据封装成Message: 数据体、回调函数的callbackId,调用JS相应函数来分发处理相应消息。
                根据Message 要调用的 java方法名,从map中取出对应的BridgeHandler对象,调用其handler方法,传入各个之前已封装好的参数,至此JS真正开始调用开发者自定义的那部分逻辑。
                当触发上面回调JS的CallBackFunction对象的逻辑,并按顺序触发到JS的消息分发逻辑时,JS会判断该消息是哪种类型:java直接调用、Java回调?  如果是Java回调操作,则从事先存储的map中按照callBackId取出对应的回调函数,并执行。


二、Java调用JS的过程
(有空再补)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值