原生代碼和JS交互說明javascript
原則前端
1.接口不要定義返回值,JS有獲取數據需求的狀況經過回調函數的方式實現java
2.儘可能保證iOS和Android端一致,簡化JS端的使用android
iOS端web
iOS端目前使用WKWebview加載前端Html。瀏覽器
JS調用OC接口WKWebView提供了postMessage的機制來讓JS調用OC接口: 函數
window.webkit.messageHandlers[namespace].postMessage(JSON.stringify(wrap));post
OC回調JS函數[self.webView evaluateJavaScript:js completionHandler:];動畫
bridge.js爲方便JS端調用,在註冊了OC方法後,須要再bridge.js中定義好JS函數,例如: this
kf.getResourceInfo = function (callBackName) { calliOSFunction("kf","getResourceInfo","",callBackName); };
bridge.js 在webview加載頁面時會自動注入到頁面中,JS端可直接調用這裏聲明的函數
Android端
Android使用QQ提供的X5內核WebView,可是該WebView在部分狀況下可能會退化會系統的WebView內核,考慮到目前咱們最低兼容到Android4.2版本,全部前端的代碼依然須要考慮兼容Android4.2的WebView
JS調用Java接口Android端只要調用: webview.addJavascriptInterface(obj, "kf");方法便可將obj對象中被@JavascriptInterface註解的方法提供給JS端調
Java調用JSwebview.loadUrl("javascript:" + function + "(\"" + data + "\")");經過此方法能夠調用JS中的函數,該函數必須在window對象下。
帶回調函數的接口爲方便JS端調用,目前要求全部帶回調函數的方法,容許傳入function對象,如:
kf.getResourceInfo = function (callback){ };
在調用時,調用方式以下:
kf.getResourceInfo(function(data){
console.log(data)
})
由於Java端並不能直接使用JS中函數對象,Java提供的接口只能接收String類型的回調函數名,因此爲了支持在前端這樣調用,須要作以下的處理
bridge.js和iOS端同樣,帶回調的JS接口須要再bridge.js中從新聲明, 在assets下的android_bridge.js中:
kf.getResourceInfo = function(callback){
win.kf._getResourceInfo(wrapCallback("getResourceInfo", callback));
};
和iOS端不一樣的時,Android端僅須要從新聲明帶回調函數的方法,無返回值的不須要從新聲明
@CallbackFunction註解請注意上面bridge.js中出現的 _getResourceInfo 方法調用,該方法在Java的接口中並不存在,它是在編譯的時候自動生成的,實際的Java方法聲明以下: public class DetailJsFunction extends BaseJsFunction {
@CallbackFunction
public void getResourceInfo(final String callback) {
webView.callJsFunction(callback, resourceInfo);
}
}
全部被@CallbackFunction註解的方法,在編譯時,會自動生成一個新的代理類,該代理類中會自動追加一個 "_" + 原方法名的方法,因此在JS中能夠直接以:
win.kf._getResourceInfo(wrapCallback("getResourceInfo", callback));的方式調用
使用JsFunctionProxy爲了使上述方式生效,須要經過JsFunctionProxy來建立要注入給JS的對象, 以下: detailJsFunction = JsFunctionProxy.inject(DetailJsFunction.class, this, webView);
webView.injectJsObject(detailJsFunction, "kf");這裏的DetailJsFunction不能是內部類了,必須是public的獨立類,因此有些狀況可能會略有不便
其餘
1.除了上述兩種原生和JS交互方案,Android和iOS均可以經過攔截特定的scheme的方式來和JS通訊,這種方式效率較低,可是最通用,有興趣的同窗可自行搜索相關資料。
2.Android和iOS的bridge.js代碼目前還須要手動維護,可是其實都是能夠自動生成的,有興趣的同窗能夠搞一下。
3.Android端的實現如今有點複雜,有興趣的同窗能夠去了解下Java編譯時代碼生成。
/* H5和iOS 客戶端交互問題總結 1.Control + Alt + T 【讓標籤包裹一段內容】 2.直接返回值/回調【設置】 3.iOS 注入的時機 4.客戶端調用JS的過程 【A:Objective-C調H五、B:H5調Objective-C】 5.客戶端/前端自測->Remote device 6.JS 傳參數文檔說明 7.屢次點擊會重複調用客戶端方法 8.交互過程當中的細節問題未考慮 9.Android 方法名的下劃線問題 10.難以判斷出現的問題 11.瀏覽器的兼容性問題 12.:ResultType Json kit WebStorm : *Remote Devices {Android} *W2 代理 *自測模板頁 *自升級HTML *加載WebView動畫 */