Cordova框架的“曲線救國”

前言

《Cordova》框架大家應(yīng)該都不陌生逆瑞,它是用來構(gòu)建JSBridge的一個(gè)框架荠藤,除了Cordova以外,我們耳熟能詳?shù)倪€有《WebViewJavascriptBridge》框架也是用來解決這個(gè)問題获高。他們有個(gè)共同特點(diǎn)哈肖,就是不約而同的使用了URL攔截的方式構(gòu)建的bridge。然而URL攔截的方式并不安全念秧,但是這兩個(gè)框架使用起來是安全的淤井,那么以Cordova為例,它是怎么處理這個(gè)問題的出爹?還是說就沒有處理庄吼?關(guān)于這個(gè)問題,實(shí)際上Cordova框架內(nèi)部是做了處理的严就,本篇主要針對Cordova對于URL攔截方式進(jìn)行通信做了哪些優(yōu)化(曲線救國)進(jìn)行分析总寻。

Cordova在iOS端是怎么通信的,我之前的文章《cordova-ios源碼解析》講的很清楚了梢为,在iOS端主要是圍繞著一個(gè)queue數(shù)組進(jìn)行的渐行,具體怎么進(jìn)行的本篇不做分析了轰坊,具體可以看前面提到的文章了解下。

本篇主要圍繞以下三點(diǎn)進(jìn)行分析為什么叫曲線救國:

  • 1.js在給native發(fā)送假請求的時(shí)候做了什么
  • 2.實(shí)際上js是怎樣將各種參數(shù)傳遞給native的
  • 3.pokeNative優(yōu)化了什么

js在給native發(fā)送假請求的時(shí)候做了什么

真相都在cordova.js里面祟印,作為一個(gè)未入門的前端來說肴沫,對于cordova.js只能做一個(gè)簡要分析,主要是針對上面提到的三點(diǎn)蕴忆,看代碼颤芬。

function iOSExec() {
    //刪除了一些不在本篇討論范圍內(nèi)的代碼
    var command = [callbackId, service, action, actionArgs];
    commandQueue.push(JSON.stringify(command));
    if (!isInContextOfEvalJs && commandQueue.length == 1) {
        pokeNative();
    }
}

在js端調(diào)用cordova插件的時(shí)候,代碼會走進(jìn)cordova.js里面的這個(gè)方法套鹅,push()函數(shù)實(shí)際上就是OC中的addObject:操作站蝠,commendQueue為cordova.js內(nèi)維護(hù)的全局?jǐn)?shù)組,commandQueue.push就是像commendQueue數(shù)組的最后面添加了一個(gè)對象卓鹿,也就是被轉(zhuǎn)為json格式的command對象菱魔。那么實(shí)際上在前端連續(xù)多次頻繁的調(diào)用插件的時(shí)候,插件的command信息都會被存儲在commandQueue中而不是把每一個(gè)通信都要去做一個(gè)假請求吟孙。通過if (!isInContextOfEvalJs && commandQueue.length == 1)這個(gè)判斷可以看到如果commandQueue中的調(diào)用次數(shù)不為一澜倦,也就是說可能有多個(gè)的時(shí)候,是不會執(zhí)行pokeNatie()的杰妓,pokeNative實(shí)際為發(fā)送假請求的具體實(shí)現(xiàn)藻治,后面會講到。從而也就避免了插件被頻繁調(diào)用所引起的通信丟失的情況稚失。

那么問題來了栋艳,插件的調(diào)用都被存儲在了commandQueue中,native端怎么獲取句各。這也是我們要討論的第二個(gè)問題。

實(shí)際上js是怎樣將各種參數(shù)傳遞給native的

那么這個(gè)問題我們需要分析下另一個(gè)函數(shù)晴叨,看代碼:

iOSExec.nativeFetchMessages = function() {
    if (failSafeTimerId) {
        clearTimeout(failSafeTimerId);
        failSafeTimerId = 0;
    }
    if (!commandQueue.length) {
        return '';
    }
    var json = '[' + commandQueue.join(',') + ']';
    commandQueue.length = 0;
    return json;
};

這是native端收到cordova.js的pokeNative發(fā)出的假請求會調(diào)用的函數(shù)凿宾,這個(gè)json對象存儲的正是commandQueue中的插件調(diào)用信息,那么不難看出兼蕊,實(shí)際上Cordova內(nèi)通信參數(shù)并不是在URL上傳遞初厚,而是JS端告訴Native過來取,大概意思就是我這有好多都取過去吧孙技。實(shí)際上只pokeNative()了一次产禾,那么插件調(diào)用就都被native端取走了,這樣也就避免了快速的頻繁的發(fā)假請求而導(dǎo)致通信丟失問題牵啦。

pokeNative優(yōu)化了什么

實(shí)際上經(jīng)過了上面兩步亚情,還是不夠安全的,因?yàn)橛幸环N情況哈雏,那就是當(dāng)前端的第一次調(diào)用剛好結(jié)束的時(shí)候發(fā)生了第二次調(diào)用楞件,這個(gè)時(shí)候已經(jīng)執(zhí)行了commandQueue.length = 0;函數(shù)衫生,也就是說commandQueue已經(jīng)被清空了,那么就會執(zhí)行pokeNative()函數(shù)土浸,去發(fā)一個(gè)假請求給native端罪针,這樣就導(dǎo)致了連續(xù)的兩次假請求發(fā)生。實(shí)際上這一塊cordova.js也是做了處理的黄伊,詳情在pokeNative()里面泪酱,看代碼:

function pokeNative() {
    //代碼刪減部分
    failSafeTimerId = setTimeout(function() {
        if (commandQueue.length) {
            // CB-10106 - flush the queue on bridge change
            if (!handleBridgeChange()) {
                pokeNative();
             }
        }
    }, 50);
}

setTimeout()函數(shù)在javaScript里面相當(dāng)于添加了個(gè)定時(shí)器,也就是在50毫秒之后再執(zhí)行pokeNative()函數(shù)还最,這樣也就是做了一個(gè)50毫秒的間隔脱篙,從而避免了快速的兩次調(diào)用族操。這一塊pokeNative()函數(shù)內(nèi)部代碼注釋也有解釋,通信效率會降低7%,但是畢竟這種情況不多胶果,而且7%也在我們能接受的范圍內(nèi)。

總結(jié)

通過上面的三部分瓢捉,應(yīng)該很明顯的看到了為了構(gòu)建這個(gè)bridge并保證他的安全性逼裆,是下了一番苦工的」际幔基于URL攔截的方式粱甫,隨著JSCore和WKWebView的新特性的出現(xiàn)也正在被逐漸的取締,但是Cordova框架不單單給我們提供了一種通信方式作瞄,更多的是它的設(shè)計(jì)思想茶宵,以及對hybrid框架的交互設(shè)計(jì)理念,如果有一天需要我們自己來做hybrid框架宗挥,我認(rèn)為除了改變一下通信方式以外乌庶,對于Cordova框架的其他部分都是很值得我們?nèi)W(xué)習(xí)的。

本文屬于原創(chuàng)契耿,轉(zhuǎn)載注明出處瞒大。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市搪桂,隨后出現(xiàn)的幾起案子透敌,更是在濱河造成了極大的恐慌,老刑警劉巖踢械,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酗电,死亡現(xiàn)場離奇詭異,居然都是意外死亡内列,警方通過查閱死者的電腦和手機(jī)撵术,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來德绿,“玉大人荷荤,你說我怎么就攤上這事退渗。” “怎么了蕴纳?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵会油,是天一觀的道長。 經(jīng)常有香客問我古毛,道長翻翩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任稻薇,我火速辦了婚禮嫂冻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘塞椎。我一直安慰自己桨仿,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布案狠。 她就那樣靜靜地躺著服傍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骂铁。 梳的紋絲不亂的頭發(fā)上吹零,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機(jī)與錄音拉庵,去河邊找鬼灿椅。 笑死,一個(gè)胖子當(dāng)著我的面吹牛钞支,可吹牛的內(nèi)容都是我干的茫蛹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼烁挟,長吁一口氣:“原來是場噩夢啊……” “哼麻惶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起信夫,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卡啰,沒想到半個(gè)月后静稻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡匈辱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年振湾,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亡脸。...
    茶點(diǎn)故事閱讀 39,841評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡押搪,死狀恐怖树酪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情大州,我是刑警寧澤续语,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站厦画,受9級特大地震影響疮茄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜根暑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一力试、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧排嫌,春花似錦畸裳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至薇芝,卻和暖如春蓬抄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背夯到。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工嚷缭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人耍贾。 一個(gè)月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓阅爽,卻偏偏與公主長得像,于是被迫代替她去往敵國和親荐开。 傳聞我的和親對象是個(gè)殘疾皇子付翁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容