Android JsBridge實(shí)戰(zhàn) 打造專屬你的Hybrid APP

更多文章請(qǐng)關(guān)注:開發(fā)者技術(shù)前線

Android開發(fā)目前現(xiàn)狀來說,開發(fā)者大部分時(shí)間花在UI的屏幕適配上,使用原生控件開發(fā)成本已不是那么的理想,鑒于很多項(xiàng)目保持和iOS一致的UI界面風(fēng)格,至使移動(dòng)UI開發(fā)成本花費(fèi)更大的代價(jià),因此目前結(jié)合H5和原生控件混合開發(fā)是解決UI適配的一種很好的選擇, 因此基于網(wǎng)頁形式的插件更新業(yè)務(wù)功能出現(xiàn)了,處于APP性能的考慮,Android也會(huì)使用java和native層(C,C++)進(jìn)行結(jié)合。無論是哪種結(jié)合,其實(shí)原理都差不多,只要按照它的協(xié)議來是很容易的,今天我們僅對(duì)于H5和Java層結(jié)合的混合開發(fā),了解WebViewJavascriptBridge的使用。


** 什么是JsBridge**

WebViewJavascriptBridge是移動(dòng)UIView和Html交互通信的橋梁,用作者的話來說就是實(shí)現(xiàn)java(ios為oc)和js的互相調(diào)用的橋梁。替代了WebView的自帶的JavascriptInterface的接口,使得開發(fā)者更方便的讓js和native靈活交互,使我們的開發(fā)更加靈活和安全。

JSBridge的優(yōu)點(diǎn)

Android API 4.4以前,谷歌的webview存在安全漏洞,網(wǎng)站可以通過js注入就可以隨便拿到客戶端的重要信息,甚至輕而易舉的調(diào)用本地代碼進(jìn)行流氓行為,谷歌后來發(fā)現(xiàn)有此漏洞后,在API 4.4以后增加了防御措施,如果用js調(diào)用本地代碼,開發(fā)者必須在代碼申明JavascriptInterface, 列如在4.0之前我們要使得webView加載js只需如下代碼:

mWebView.addJavascriptInterface(new JsToJava(), "myjsfunction");

4.4之后使用時(shí)需要在調(diào)用Java方法加入@JavascriptInterface注解,如果代碼無此申明,那么也就無法使得js生效,也就是說這樣就可以避免惡意網(wǎng)頁利用js對(duì)客戶端的進(jìn)行竊取和攻擊。 但是即使這樣,我們很多時(shí)候需要在js調(diào)用本地java代碼的時(shí)候,要做一些判斷和限制,或者有的場(chǎng)景也會(huì)做些過濾或者對(duì)用戶友好提示,甚至更復(fù)雜的Hybrid模式下,需要js和native之間進(jìn)行交互通訊,拍照上傳,因此原生的JavascriptInterface 就比較維護(hù)了,特此有了基于JavascriptInterface 封裝的WebViewJavascriptBridge框架。

使用JsBridge正確姿勢(shì)

1 添加依賴
Eclipse:
導(dǎo)入jar包
直接copy jar的源碼到工程
JsBridge. jar可以到gitHub上直接下載。
Android Studio:

配置gradle

dmo.jpg

2 WebView需使用jsBridge的webView

code2.jpg

JS和Native交互
JS是基于訂閱和回調(diào)來實(shí)現(xiàn)Js和native交互的,我們需要在java中訂閱,然后Js中回調(diào),反之也可以。
3.1 Java
registerHandler()用來注冊(cè)一個(gè)java函數(shù),來實(shí)現(xiàn)js回調(diào)的handler,

第一個(gè):訂閱的方法名
第二個(gè): 回調(diào)Handler , 參數(shù)返回js請(qǐng)求的resqustData,function.onCallBack()回調(diào)到j(luò)s,調(diào)用function(responseData)

//必須和js同名函數(shù),注冊(cè)具體執(zhí)行函數(shù),類似java實(shí)現(xiàn)類

webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
function.onCallBack( data + “java”);
}
});

3.2 JS
Js代碼需要用window.WebViewJavascriptBridge.callHandler同步回調(diào)java層注冊(cè)的同名函數(shù),這和java和c庫的jni調(diào)用如出一轍,方法名必須和Java層保持一致

第一參數(shù):方法名
第二個(gè):js調(diào)用native的請(qǐng)求參數(shù)
第三個(gè):js在被回調(diào)后具體執(zhí)行方法,responseData為java層回傳jsonStr.

window.WebViewJavascriptBridge.callHandler(
'submitFromWeb',
{'param': requsetData }, function(responseData) {
// do somrthing
});

案列實(shí)踐

** 1.Activity**
初始化WebView,設(shè)置必要的參數(shù)。

code5.jpg

需要自定義HandlerCallBack和WebViewClent;


code6.jpg

加載網(wǎng)頁 支持本地和遠(yuǎn)程


23.jpg

1 java調(diào)用js函數(shù)

QQ截圖20160602195209.jpg

js同樣需要java注冊(cè)訂閱的同名函數(shù)

24.jpg

2 JS調(diào)用Java代碼
反之js調(diào)用java代碼
Js 訂閱一個(gè)叫functionInJs的方法

27.jpg

3 注意事項(xiàng)
無論怎樣形式的交互,Js 必須要初始化jsBridge

28.jpg

效果圖:

main.png

代碼展示
1 Acitivty

30.jpg

34.jpg

通過實(shí)例化webView,用法和安卓原生的view沒多大區(qū)別,設(shè)置WebChromClient, 設(shè)置加載的html(同樣支持網(wǎng)絡(luò)和本地文件),接著我們需要給web注冊(cè)和html端約定好的js方法名。代碼列舉的submitFromweb和js的執(zhí)行的方法名一致,玩過NDK的JNI調(diào)用的朋友也知道必須和c代碼之間有個(gè)約定,其實(shí)js橋和jni有點(diǎn)類似
2 js代碼

![Uploading 95852_743830.jpg . . .]
56565.jpg

這段代碼不難理解,我們對(duì)上面的id為enter的Button注冊(cè)了一個(gè)點(diǎn)擊事件,點(diǎn)擊后執(zhí)行以下testClick()方法,依次類推,其他Button注冊(cè)事件相同,當(dāng)點(diǎn)擊“發(fā)消息給Native”的按鈕時(shí),Js通過webWiew的jsBridage.send()發(fā)送一條數(shù)據(jù)給java層(密碼和用戶名),同時(shí)執(zhí)行function()來執(zhí)行應(yīng)java層回調(diào)函數(shù)的。此demo中是把java返回的數(shù)據(jù)插入到ID為”show”的div里面去。
testClick1():此方法中調(diào)用callHandler來調(diào)用Java代碼的submitFromweb同名函數(shù),可以結(jié)合上面的Activty的代碼理解下,此函數(shù)調(diào)用我們已在java已注冊(cè)訂閱
//必須和js同名函數(shù),注冊(cè)具體執(zhí)行函數(shù),類似java實(shí)現(xiàn)類。

5454.jpg

3. H5

h5.jpg

這里so ez ! 你不必care
h5實(shí)現(xiàn)文件上傳
打開相冊(cè).png


四 總結(jié)

通過以上的API介紹,代碼示例,不難發(fā)現(xiàn)此框架的優(yōu)雅和簡(jiǎn)便,對(duì)js和java雙方來說,如果Html中的js需要調(diào)用java代碼,而java代碼沒做任何實(shí)現(xiàn),那么js中方法也是無效的,反之java代碼注冊(cè)的函數(shù),沒在js里去回調(diào)實(shí)現(xiàn),那么Java層也是無法獲取js中數(shù)據(jù)的,由此可見,此通信是雙方支持的,必須由雙方來約定,這樣就避免了Android之前存在的js注入漏洞,也很大的提高了安全性,也可以保證我們的網(wǎng)頁數(shù)據(jù)不被第三方的APP獲取,具體來講,列如我們的項(xiàng)目某一個(gè)web的h5界面,被系統(tǒng)瀏覽器或者其他第三方App的惡意加載,那么它的java代碼想調(diào)用你的js函數(shù),實(shí)現(xiàn)需要你的H5的Js先注冊(cè),不然跟本無法調(diào)用你的h5信息。這樣保證了這個(gè)html數(shù)據(jù)的安全性,,第三方的瀏覽器可以加載預(yù)覽你的網(wǎng)頁,但是第三方j(luò)ava無法和你的的h5中的js交互通信的。同樣加載我們自己的APP加載第三方的網(wǎng)頁時(shí)候,我們可以對(duì)第三方網(wǎng)頁進(jìn)行一些行為的過濾,方便保護(hù)我們手機(jī)的安全,列如第三方可以獲取本機(jī)地址時(shí)我們可以提示用戶授權(quán)。
雖然H5并不屬于插件的一種,但是借助h5我可以方便的去更新一些運(yùn)營(yíng)活動(dòng),和某些需要經(jīng)常需要更換UI的業(yè)務(wù)功能的地方,由于本文是從CSDN遷移過來的,原文實(shí)在一年前寫的,所以帶來的墳貼感覺請(qǐng)見諒。
原文csdn請(qǐng)戳:這里

以上只JSBridge的使用姿勢(shì),以后再給大家解剖下JsBridge的內(nèi)部實(shí)現(xiàn)。


項(xiàng)目地址
項(xiàng)目實(shí)例:https://github.com/NeglectedByBoss/JsBridge_Android
英文介紹:https://github.com/lzyzsd/JsBridge

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容