從Native和H5兩端看JsBridge

之前一直在使用JsBridge,也知道大概的原理,但是沒有去深究。最近有空研究了一下。以Android和H5兩端的視角分析一下其中的原理

需求背景

Native 加載 H5 頁面豪嗽,H5頁面可以調(diào)用Native的方法,Native也可以調(diào)用H5頁面的方法豌骏,并且可以傳遞數(shù)據(jù)和設(shè)置回調(diào)龟梦。
這基本上是一個Hybrid應(yīng)用所具有的基本功能,下面就來分析下具體的實現(xiàn)過程窃躲。

官方方案

  1. Android 4.2 之前有漏洞计贰,js可以訪問任何public方法,最主要的是getClass方法蒂窒,至于具體情況躁倒,有興趣的可以網(wǎng)絡(luò)search一下荞怒。
  2. Android 4.2 之后添加了限制,只有@JavascriptInterface注解的方法秧秉,才能在js中訪問褐桌。

簡要說明

如果只考慮Android4.2 之后的版本,可以使用官方方案象迎,雖說增加了安全性荧嵌,但是也不保證絕對安全。另一方面還需要解決Android 4.2之前的版本砾淌,所以就衍生出了第三種解決方案啦撮。

業(yè)界通常的做法就是攔截js的prompt/alert/confirm方法,然后會執(zhí)行到WebChromeClient中相應(yīng)的方法onJsPrompt/onJsAlert/onJsConfirm拇舀,從而做到j(luò)s調(diào)用Native的方法逻族。因為alert和confirm方法在js中是常用的蜻底,prompt方法不常用骄崩,所以一般選擇攔截prompt方法。

如果只是說原理薄辅,那現(xiàn)在就可以結(jié)束了要拂。可是我是一個較真的人站楚,所以有了下文脱惰。如果你也不滿足于上面提到的這些,就看下面的具體分析吧窿春!

自定義方案

加載

上面說了可以通過攔截js的prompt函數(shù)來執(zhí)行Native的onJsPrompt方法拉一,從而執(zhí)行你想執(zhí)行的Native方法。但這僅僅是原理旧乞,在一個App中怎么判斷我要執(zhí)行哪一個方法呢蔚润?調(diào)用的方法有沒有限制?下面就來介紹下我司的實際解決方案

  1. 在App中定義所有可以被Js訪問的方法尺栖,由于方法來自各個模塊嫡纠,方法名可能重復(fù),所以定義了module的概念延赌,即定義所有的module除盏,存在Bridge類的map<moduleName,ExportModule>,這里定為JavascriptBridge(下同)挫以,并提供給外部獲取modules {"module": moduleName,"methods": ["methodA",....]}
    說明:
    1. 識別method的方式跟Google官方的方案一樣者蠕,采用注解的方式。即在method上面添加注解掐松,這里定為JsBridge(下同)
    2. ExportModule 類有 String moduleName; Class moduleClass; 兩個變量
    和一個 private map 提供根據(jù)注解名找到所有提供給js的Method蠢棱,存放在map<"methodA",MethodA>中,methodA為注解值锌杀,MethodA為Method.Class
  2. 自定義webView 添加UserAgent 標識,這里定為 "droid"(下同) 泻仙,這里的目的是讓js識別是需要處理的url
  3. Native load(url)
    小總結(jié):以上三部是在Native需要做的事情糕再,主要就是準備給js調(diào)用的方法,加載url
  4. H5頁面收到請求url玉转,引入bridge.js(下同) 會去初始化突想,會根據(jù)userAgent判斷是否需要去處理,需要處理的話究抓,通過調(diào)用window.prompt來調(diào)用Native的onJsPrompt方法獲取Native的JavascriptBridge中存儲的modules猾担,然后注冊到bridge.js
    小總結(jié):這一步就是js初始化的時候獲取Native的modules,注冊到j(luò)s中

總結(jié):整個流程就是Native和Js兩端各準備一個bridge刺下,Native的bridge提供modules绑嘹,js的bridge注冊Native提供的modules。這就是bridge存在的意義--提供一個橋梁橘茉,讓兩邊通信

加載過程.png

調(diào)用

H5調(diào)用Native

  1. js 提供一個方法bridgecall (下同)工腋,用來拼裝一個url 包括 type: 調(diào)用方法/回調(diào)方法 module method args。
  2. bridgecall 會 document.createElement 一個iFrame畅卓,設(shè)置它的src為上面拼裝的url擅腰,這樣就會發(fā)起一個url的請求,隨后移除掉這個iFrame
  3. H5調(diào)用js注冊的module的方法翁潘,會統(tǒng)一調(diào)用到invokeNative方法調(diào)用bridgecall方法趁冈,從而發(fā)起一個url請求
  4. webViewClient的shouldOverrideLoading()方法會攔截到url,然后解析url拜马,找到相應(yīng)的Method執(zhí)行渗勘。

Native調(diào)用 H5

  1. loadurl("javascript:js的方法invokeJSMethod(module,method,args)"),這里的args俩莽,如果有回調(diào)函數(shù)旺坠,bridge會存一個map<callbackidFormat,callBackFun> ,然后把callbackIdFormat作為參數(shù)加載args中豹绪。
  2. js 執(zhí)行invokeJSMethod方法价淌,解析callbackIdFormat,如果匹配到的話說明有回調(diào)函數(shù)瞒津,在執(zhí)行完方法后會把callbackIdFormat作為參數(shù)蝉衣,執(zhí)行callbackNavite方法
  3. callbackNative 到invokeNative方法調(diào)用bridgecall發(fā)起url請求
  4. webViewClient的shouldOverrideLoading()方法會攔截到url,解析到時回調(diào)請求巷蚪,就去獲取callbackidFormat對應(yīng)的callBackFun病毡。

總結(jié):
H5調(diào)用Native就是拼裝url,發(fā)起請求屁柏,Native攔截去請求Native的方法啦膜,如需要回調(diào)有送,之前url帶上回調(diào)函數(shù),去執(zhí)行js的函數(shù)僧家,跟Native調(diào)用H5一樣雀摘。
Native調(diào)用H5就是執(zhí)行H5中的方法,若需要回調(diào)八拱,跟H5調(diào)用Native一樣

加載和互相調(diào)用.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阵赠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子肌稻,更是在濱河造成了極大的恐慌清蚀,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件爹谭,死亡現(xiàn)場離奇詭異枷邪,居然都是意外死亡,警方通過查閱死者的電腦和手機诺凡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門东揣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绑洛,你說我怎么就攤上這事救斑⊥荆” “怎么了真屯?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長穷娱。 經(jīng)常有香客問我绑蔫,道長,這世上最難降的妖魔是什么泵额? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任配深,我火速辦了婚禮,結(jié)果婚禮上嫁盲,老公的妹妹穿的比我還像新娘篓叶。我一直安慰自己,他們只是感情好羞秤,可當我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布缸托。 她就那樣靜靜地躺著,像睡著了一般瘾蛋。 火紅的嫁衣襯著肌膚如雪俐镐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天哺哼,我揣著相機與錄音佩抹,去河邊找鬼叼风。 笑死,一個胖子當著我的面吹牛棍苹,可吹牛的內(nèi)容都是我干的无宿。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼枢里,長吁一口氣:“原來是場噩夢啊……” “哼懈贺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起坡垫,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤梭灿,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后冰悠,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堡妒,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年溉卓,在試婚紗的時候發(fā)現(xiàn)自己被綠了皮迟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡桑寨,死狀恐怖伏尼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情尉尾,我是刑警寧澤爆阶,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站沙咏,受9級特大地震影響辨图,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肢藐,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一俊戳、第九天 我趴在偏房一處隱蔽的房頂上張望踩官。 院中可真熱鬧棱烂,春花似錦占遥、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至速勇,卻和暖如春晌砾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烦磁。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工养匈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留哼勇,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓呕乎,卻偏偏與公主長得像积担,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子猬仁,可洞房花燭夜當晚...
    茶點故事閱讀 42,792評論 2 345

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