原生代碼和JS交互說明

原生代碼和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動畫
*/
相關文章
相關標籤/搜索