原生代碼和JS交互說明


原生代碼和JS交互說明

原則

1.接口不要定義返回值,JS有獲取數據需求的情況通過回調函數的方式實現

2.盡量保證iOS和Android端一致,簡化JS端的使用

iOS端

 

iOS端目前使用WKWebview加載前端Html。

JS調用OC接口WKWebView提供了postMessage的機制來讓JS調用OC接口:   

window.webkit.messageHandlers[namespace].postMessage(JSON.stringify(wrap));

OC回調JS函數[self.webView evaluateJavaScript:js completionHandler:];

bridge.js為方便JS端調用,在注冊了OC方法后,需要再bridge.js中定義好JS函數,例如:   

               

               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調H5、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動畫
*/

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM