更多文章請關注:開發者技術前線
Android開發目前現狀來說,開發者大部分時間花在UI的屏幕適配上,使用原生控件開發成本已不是那么的理想,鑒于很多項目保持和iOS一致的UI界面風格,至使移動UI開發成本花費更大的代價,因此目前結合H5和原生控件混合開發是解決UI適配的一種很好的選擇, 因此基于網頁形式的插件更新業務功能出現了,處于APP性能的考慮,Android也會使用java和native層(C,C++)進行結合。無論是哪種結合,其實原理都差不多,只要按照它的協議來是很容易的,今天我們僅對于H5和Java層結合的混合開發,了解WebViewJavascriptBridge的使用。
** 什么是JsBridge**
WebViewJavascriptBridge是移動UIView和Html交互通信的橋梁,用作者的話來說就是實現java(ios為oc)和js的互相調用的橋梁。替代了WebView的自帶的JavascriptInterface的接口,使得開發者更方便的讓js和native靈活交互,使我們的開發更加靈活和安全。
JSBridge的優點
Android API 4.4以前,谷歌的webview存在安全漏洞,網站可以通過js注入就可以隨便拿到客戶端的重要信息,甚至輕而易舉的調用本地代碼進行流氓行為,谷歌后來發現有此漏洞后,在API 4.4以后增加了防御措施,如果用js調用本地代碼,開發者必須在代碼申明JavascriptInterface, 列如在4.0之前我們要使得webView加載js只需如下代碼:
mWebView.addJavascriptInterface(new JsToJava(), "myjsfunction");
4.4之后使用時需要在調用Java方法加入@JavascriptInterface注解,如果代碼無此申明,那么也就無法使得js生效,也就是說這樣就可以避免惡意網頁利用js對客戶端的進行竊取和攻擊。 但是即使這樣,我們很多時候需要在js調用本地java代碼的時候,要做一些判斷和限制,或者有的場景也會做些過濾或者對用戶友好提示,甚至更復雜的Hybrid模式下,需要js和native之間進行交互通訊,拍照上傳,因此原生的JavascriptInterface 就比較維護了,特此有了基于JavascriptInterface 封裝的WebViewJavascriptBridge框架。
使用JsBridge正確姿勢
1 添加依賴
Eclipse:
導入jar包
直接copy jar的源碼到工程
JsBridge. jar可以到gitHub上直接下載。
Android Studio:
配置gradle
2 WebView需使用jsBridge的webView
JS和Native交互
JS是基于訂閱和回調來實現Js和native交互的,我們需要在java中訂閱,然后Js中回調,反之也可以。
3.1 Java
registerHandler()用來注冊一個java函數,來實現js回調的handler,
第一個:訂閱的方法名
第二個: 回調Handler , 參數返回js請求的resqustData,function.onCallBack()回調到js,調用function(responseData)
//必須和js同名函數,注冊具體執行函數,類似java實現類
webView.registerHandler("submitFromWeb", new BridgeHandler() {
@Override
public void handler(String data, CallBackFunction function) {
function.onCallBack( data + “java”);
}
});
3.2 JS
Js代碼需要用window.WebViewJavascriptBridge.callHandler同步回調java層注冊的同名函數,這和java和c庫的jni調用如出一轍,方法名必須和Java層保持一致
第一參數:方法名
第二個:js調用native的請求參數
第三個:js在被回調后具體執行方法,responseData為java層回傳jsonStr.
window.WebViewJavascriptBridge.callHandler(
'submitFromWeb',
{'param': requsetData }, function(responseData) {
// do somrthing
});
案列實踐
** 1.Activity**
初始化WebView,設置必要的參數。
需要自定義HandlerCallBack和WebViewClent;
加載網頁 支持本地和遠程
1 java調用js函數
js同樣需要java注冊訂閱的同名函數
2 JS調用Java代碼
反之js調用java代碼
Js 訂閱一個叫functionInJs的方法
3 注意事項
無論怎樣形式的交互,Js 必須要初始化jsBridge
效果圖:
代碼展示
1 Acitivty
通過實例化webView,用法和安卓原生的view沒多大區別,設置WebChromClient, 設置加載的html(同樣支持網絡和本地文件),接著我們需要給web注冊和html端約定好的js方法名。代碼列舉的submitFromweb和js的執行的方法名一致,玩過NDK的JNI調用的朋友也知道必須和c代碼之間有個約定,其實js橋和jni有點類似
2 js代碼
這段代碼不難理解,我們對上面的id為enter的Button注冊了一個點擊事件,點擊后執行以下testClick()方法,依次類推,其他Button注冊事件相同,當點擊“發消息給Native”的按鈕時,Js通過webWiew的jsBridage.send()發送一條數據給java層(密碼和用戶名),同時執行function()來執行應java層回調函數的。此demo中是把java返回的數據插入到ID為”show”的div里面去。
testClick1():此方法中調用callHandler來調用Java代碼的submitFromweb同名函數,可以結合上面的Activty的代碼理解下,此函數調用我們已在java已注冊訂閱
//必須和js同名函數,注冊具體執行函數,類似java實現類。
3. H5
這里so ez ! 你不必care
h5實現文件上傳
四 總結
通過以上的API介紹,代碼示例,不難發現此框架的優雅和簡便,對js和java雙方來說,如果Html中的js需要調用java代碼,而java代碼沒做任何實現,那么js中方法也是無效的,反之java代碼注冊的函數,沒在js里去回調實現,那么Java層也是無法獲取js中數據的,由此可見,此通信是雙方支持的,必須由雙方來約定,這樣就避免了Android之前存在的js注入漏洞,也很大的提高了安全性,也可以保證我們的網頁數據不被第三方的APP獲取,具體來講,列如我們的項目某一個web的h5界面,被系統瀏覽器或者其他第三方App的惡意加載,那么它的java代碼想調用你的js函數,實現需要你的H5的Js先注冊,不然跟本無法調用你的h5信息。這樣保證了這個html數據的安全性,,第三方的瀏覽器可以加載預覽你的網頁,但是第三方java無法和你的的h5中的js交互通信的。同樣加載我們自己的APP加載第三方的網頁時候,我們可以對第三方網頁進行一些行為的過濾,方便保護我們手機的安全,列如第三方可以獲取本機地址時我們可以提示用戶授權。
雖然H5并不屬于插件的一種,但是借助h5我可以方便的去更新一些運營活動,和某些需要經常需要更換UI的業務功能的地方,由于本文是從CSDN遷移過來的,原文實在一年前寫的,所以帶來的墳貼感覺請見諒。
原文csdn請戳:這里
以上只JSBridge的使用姿勢,以后再給大家解剖下JsBridge的內部實現。
項目地址
項目實例:https://github.com/NeglectedByBoss/JsBridge_Android
英文介紹:https://github.com/lzyzsd/JsBridge