您的位置:首页 > 移动开发

BridgeWebview原理简略分析

2017-07-27 15:13 239 查看
整体理解:
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方法名、传递的数据、回掉函数
functioncallHandler(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的过程
(有空再补)

Android JSBridge实现
JsBridge 实现 JavaScript 和 Java 的互相调用 - Android - 掘金
五分钟明白 JSBridge 是如何工作的? - 前端 - 掘金
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息