WebViewJavascriptBridge源码解读

JS中维护一个消息队列

     var sendMessageQueue = []; // 消息队列

JS和Native都封装消息写到该队列,然后通知对方处理

JS注册Handler

    var messageHandlers = {}; // JS 的 Handler 的 map

JS中维护HandleName和block的Map

JS 回调

    function _doSend(message, responseCallback) {
        if (responseCallback) {
            var callbackId = 'cb_'+(uniqueId++)+'_'+new Date().getTime();
            responseCallbacks[callbackId] = responseCallback;
            message['callbackId'] = callbackId;
        }
        sendMessageQueue.push(message);
        messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
    }

JS中维护callBackId和block的Map
JS发起请求的时候生成带cb_前缀的请求的callBackId,然后用该callBackId映射对应的回调block,存储在responseCallbacks中

    var responseCallbacks = {}; // JS 的 回调 的 map

Native注册Handler

// Native 的 Handler 的 map
@property (strong, nonatomic) NSMutableDictionary* messageHandlers;

Native中维护HandleName和block的Map

Native的回调

- (void)sendData:(id)data responseCallback:(WVJBResponseCallback)responseCallback handlerName:(NSString*)handlerName {
    NSMutableDictionary* message = [NSMutableDictionary dictionary];
    
    if (data) {
        message[@"data"] = data;
    }
    
    if (responseCallback) {
        NSString* callbackId = [NSString stringWithFormat:@"objc_cb_%ld", ++_uniqueId];
        self.responseCallbacks[callbackId] = [responseCallback copy];
        message[@"callbackId"] = callbackId;
    }
    
    if (handlerName) {
        message[@"handlerName"] = handlerName;
    }
    [self _queueMessage:message];
}

Native每次请求,先生成请求的callbackId(带前缀objc_cb 防止与JS的回调id碰撞)然后用该callBackId映射对应的回调block, 存储在responseCallbacks中

// Native 的 回调 的 map
@property (strong, nonatomic) NSMutableDictionary* responseCallbacks;

JS调用Native

存一个带callId和参数的msg到消息队列;
回调block存到map中通过callId映射;
通过iframe发一个消息处理的请求给Native(Native通过webView代理的回调接收这个请求)

Native调用JS

通过调用js方法存一个带callId和参数的msg到消息队列;
直接调用js方法处理消息;

其他

双方在回消息的时候将callBackId名字换成responseId,通过这个字段可以区分消息类型(请求类型 回复类型)

推荐阅读更多精彩内容