摘要:以這個工具庫作為依賴,只需要編寫實(shí)際通訊接口目前混合開發(fā)的方案包括就是一種簡單的解決方案?;诮涌诹6鹊陌踩刂撇呗悦恳粋€實(shí)例也都會持有一個的實(shí)例,用于針對具體的開發(fā)接口設(shè)置安全檢查規(guī)則。
EasyBridge是一個簡單易用的js-bridge的工具庫,提供了日常開發(fā)中,JavaScript與Java之間通訊的能力,與其他常見的js-bridge工具庫實(shí)現(xiàn)方案不同,EasyBridge具備以下幾個特點(diǎn):
基于Android WebView的addJavascriptInterface特性實(shí)現(xiàn)
提供了基于接口粒度的安全管理接口
輕量級,并且簡單易用。以這個工具庫作為依賴,只需要編寫實(shí)際通訊接口
Principle目前混合開發(fā)的方案包括:
JSBridge
Cordova
React Native
Flutter
EasyBridge就是一種簡單的JSBridge解決方案。在眾多的解決方案中,基本都是在利用系統(tǒng)的WebView所開放的接口,打開Java與JavaScript通訊的渠道,這些方案的實(shí)現(xiàn)原理分別包括:
攔截onJsPrompt()方法
當(dāng)WebView中的頁面調(diào)用了JavaScript當(dāng)中的window.prompt()方法的時(shí)候,這個方法會被回調(diào)。而且這個方法不僅能獲取到JavaScript傳遞過來的string字符串內(nèi)容,同時(shí)也能返回一段string字符串內(nèi)容被JavaScript接收到,是一個相當(dāng)適合構(gòu)建bridge的入口方法。
攔截shouldOverrideUrlLoading()方法
當(dāng)頁面重新load URL或者頁面的iframe元素重新加載新的URL的時(shí)候,這個方法被回調(diào)。
addJavascriptInterface()接口
這個接口簡單卻強(qiáng)大,通過這個接口,我們能夠直接把Java中定義的對象在JavaScript中映射出一個對應(yīng)的對象,使其直接調(diào)用Java當(dāng)中的方法,但是,在android 4.1及之前的版本存在著嚴(yán)重的漏洞,所以一直被忽視。
EasyBridge在眾多的解決方案中,最終了選擇了addJavascriptInterface()接口作為方案的基礎(chǔ),主要基于以下幾點(diǎn)考量:
目前Android版本已經(jīng)到了9.0版本,市面上Android4.4之前的版本手機(jī)占有率已經(jīng)很低,很多業(yè)務(wù)都已經(jīng)把最低兼容版本定在了4.2以上,在這種情況下可以不考量4.1以下存在的漏洞問題;
addJavascriptInterface()能夠提供最簡單的同步調(diào)用
addJavascriptInterface()與evaluateJavascript()/loadUrl結(jié)合,能夠帶來更加簡單的異步調(diào)用的解決方案
方案結(jié)構(gòu)EasyBridge的方案結(jié)構(gòu)如下圖所示:
EasyBridge總共會向頁面中注入兩個JavaScript對象,:
easyBridge
在頁面加載到25%以上的時(shí)候(onProgressChanged()),通過執(zhí)行工具庫中的一個js文件注入的。這個對象主要的作用是定義了業(yè)務(wù)頁面的JavaScript代碼調(diào)用native的Java代碼的規(guī)范入口,對象中定義的一個最關(guān)鍵的函數(shù)就是callHandler(handlerName, args, callback),這就是橋梁的入口。實(shí)際上在這個方法的內(nèi)部,最終就是通過下面的_easybridge對象進(jìn)入到Java代碼層。
_easybridge
通過addJavascriptInterface()映射和注入的一個對象,這個對象提供了實(shí)質(zhì)的入口方法enqueue(),在這個方法當(dāng)中代碼的路線從JavaScript層進(jìn)入到了Java層,開啟了兩者的交互。
接口分發(fā)實(shí)際上,我們可以通過@JavascriptInterface注解開放很多的接口給JavaScript層調(diào)用,也可以通過addJavascriptInterface()映射多個Java對象到JavaScript層,但是為了維護(hù)簡單和通訊方便,EasyBridge的設(shè)計(jì)只提供了一個入口和一個出口。所有需要開放給JavaScript層的功能,都是通過構(gòu)建接口實(shí)例進(jìn)行處理。
接口的定義如下:
public interface BridgeHandler { String getHandlerName(); void onCall(String parameters, ResultCallBack callBack); SecurityPolicyChecker securityPolicyChecker(); }
實(shí)際的工作流程如下圖所示:
最開始初始化的時(shí)候需要注冊所有可以被JavaScript層調(diào)用的業(yè)務(wù)接口。在運(yùn)行的過程中,enqueue()入口當(dāng)中會根據(jù)協(xié)議定義,通過接口名稱找到對應(yīng)的處理接口實(shí)例,并觸發(fā)接口響應(yīng)。并且最終的接口響應(yīng)都在入口處進(jìn)行回傳。因此,實(shí)際上,_easybridge對象(在Java層中,其實(shí)是EasyBridge的實(shí)例)就是一個樞紐站,做任務(wù)的分派和結(jié)果的傳遞。
安全控制EasyBridge的安全檢查通過實(shí)現(xiàn)下面的接口對象來完成:
public interface SecurityPolicyChecker { boolean check(String url, String parameters); }
內(nèi)部提供了兩級的安全控制策略,分別對應(yīng)全局的安全控制策略和基于接口粒度的安全控制策略:
全局安全控制策略在EasyBridgeWebView對象當(dāng)中,持有SecurityPolicyChecker用于進(jìn)行全局的安全檢查。全局的安全檢查在EasyBridge的內(nèi)部發(fā)生在以下兩個時(shí)機(jī):
Java注入bridge的時(shí)候
根據(jù)當(dāng)前加載的頁面url和參數(shù)信息,判斷是否需要在頁面中注入bridge。如果被安全規(guī)則攔截,則之前通過addJavaScriptInterface()注入的對象會被移除,也不會向頁面中注入bridge對象,確保安全。
JavaScript調(diào)用具體的Java接口的時(shí)候
在執(zhí)行具體的Java開放的接口方法之前, 也會先觸發(fā)全局的安全檢查規(guī)則。
基于接口粒度的安全控制策略每一個BridgeHandler實(shí)例也都會持有一個SecurityPolicyChecker的實(shí)例,用于針對具體的開發(fā)接口設(shè)置安全檢查規(guī)則。每一個接口在接收到分派的指令之前,會先調(diào)用其安全控制策略,根據(jù)當(dāng)前加載的頁面地址以及傳入的指令參數(shù)判斷是否需要進(jìn)行指令的分派,否則將會直接命令安全受限,錯誤返回,結(jié)果調(diào)用。
Feture?? 注入jsbridge重試機(jī)制
?? 使用apt技術(shù)注冊handler
?? JavaScript調(diào)用Java功能
?? Java調(diào)用JavaScript功能
?? 安全控制策略
關(guān)于EasyBridge的feature的詳細(xì)說明以及整個工具庫的使用,可以參考我的GitHub倉庫中的說明。
整個工具庫比較簡單和小巧,歡迎大家對這種實(shí)現(xiàn)方案存在的問題提出改進(jìn)的意見,謝謝
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69010.html
摘要:在此次大會中,全面闡釋了極簡產(chǎn)品背后蘊(yùn)涵極深的技術(shù),首次系統(tǒng)表達(dá)了自己的產(chǎn)品理念,而大會主視覺也始終緊貼著這一理念進(jìn)行設(shè)計(jì)。視覺方向的探索本次大會最初的關(guān)鍵詞是簡和深,我們首先要做的是根據(jù)大會的主題關(guān)鍵詞,來提取出能表述大致畫面的視覺方向。2018年11月25日,UCloud用戶大會暨Think in Cloud 2018在上海如期召開。在此次大會中,UCloud全面闡釋了極簡產(chǎn)品背后蘊(yùn)涵極...
摘要:模式記錄了已得到充分證明的既有設(shè)計(jì)經(jīng)驗(yàn)。模式有助于創(chuàng)建具有指定特征的軟件。每個模式都說明了運(yùn)行階段的行為。應(yīng)用設(shè)計(jì)模式不會影響軟件系統(tǒng)的基本架構(gòu),但可能嚴(yán)重影響子系統(tǒng)的架構(gòu)。成例如何解決特定的設(shè)計(jì)問題。 學(xué)了這么久的設(shè)計(jì)模式,最近一直在看Node.js的設(shè)計(jì)模式,一直納悶為何會有模式這一類東西的存在,那么模式究竟是什么東西?后面在看了《面向模式的軟件架構(gòu)》之后才慢慢知道有了一些系統(tǒng)的概...
摘要:難以通過重構(gòu)手法完成設(shè)計(jì)的改動先想像重構(gòu)的情況。何時(shí)不該重構(gòu)現(xiàn)有代碼根本不能正常運(yùn)作?,F(xiàn)在,我可以修改這個子類而不必承擔(dān)午一中影響另一處的風(fēng)險(xiǎn)。 重構(gòu):對軟件內(nèi)部結(jié)構(gòu)的一種調(diào)整,目的是再不改變軟件的可觀察行為的前提下,提高其可理解性,降低其修改成本。 兩頂帽子 添加新功能 添加新功能時(shí)不應(yīng)該修改既有代碼,只管添加新功能,通過測試重構(gòu) 重構(gòu)時(shí)你就不能再添加功能,只管改進(jìn)程序結(jié)構(gòu),此時(shí)...
摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識,其實(shí)都是來自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。 開篇 前端開發(fā)是一個非常特殊的行業(yè),它的歷史實(shí)際上不是很長,但是知識之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研...
摘要:在他的重學(xué)前端課程中提到到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系中的重要崗位之一。大部分前端工程師的知識,其實(shí)都是來自于實(shí)踐和工作中零散的學(xué)習(xí)。一基礎(chǔ)前端工程師吃飯的家伙,深度廣度一樣都不能差。開篇 前端開發(fā)是一個非常特殊的行業(yè),它的歷史實(shí)際上不是很長,但是知識之繁雜,技術(shù)迭代速度之快是其他技術(shù)所不能比擬的。 winter在他的《重學(xué)前端》課程中提到: 到現(xiàn)在為止,前端工程師已經(jīng)成為研發(fā)體系...
閱讀 3196·2021-11-18 10:02
閱讀 1446·2021-10-12 10:08
閱讀 1239·2021-10-11 10:58
閱讀 1269·2021-10-11 10:57
閱讀 1167·2021-10-08 10:04
閱讀 2121·2021-09-29 09:35
閱讀 773·2021-09-22 15:44
閱讀 1269·2021-09-03 10:30