DSJribge js和native的互動
app要重構,想著把app端native的邏輯判斷全部放在前端,這樣如果app萬一有什麼小變動或者軟升級,不需要app升級,只升級前端就可以搞定,所以考慮把app中native的操作全部抽取為單個的功能,然後通過js呼叫native方法,同時因為有一些網路請求和加解密、ui等同步和非同步的操作,所以需要js呼叫native時,既要支援同步,也要支援非同步,在github中找了兩個庫,jsbridge和dsbridge,通過對比,最終選擇了jsbridge,原因有兩個:1,jsbridge在github的程式碼應該是作者同步有問題,最新版本少java檔案。2,dsbridge有x5、android、ios版本;所以最終選取了dsbridge。
dsbridge整合步驟(留作備用):
1,下載dsbridge3.0原始碼,把java檔案和js檔案拿出來
2,app新建module,把java檔案進行繼承和封裝
3,前端寫個空的htmls頁面,作為dsbridge的js和我自定義js方法的橋樑,都引入html檔案,注意在引入js檔案時,dsjribge的js要在上面,自定義的js檔案要在下面,因為htmls載入js是由上往下
4,js呼叫本地方法,區分同步和非同步,引數為一個json字串,通過controlType區分操作型別,controlParams為操作需要的json字串型別的引數(controlType為後臺資料庫配置,前端保持和資料庫同步),如果app需要修改操作步驟和操作邏輯,就可以通過controlType來修改,如果要新增加功能,就只能升級app
具體js方法:
js呼叫native方法,同步拿到native執行結果(一般為邏輯判斷)
//同步呼叫native,methodPath為navite設定的工作空間的方法名(工作空間.方法名,dsbridge封裝的格式),params為js傳給native的引數,包含controlType和controlMsg function jsCallNative4Syn(methodPath,params){ return dsBridge.call(methodPath,params); }
js呼叫native方法,通過回撥非同步拿到返回結果(一般為網路請求、延遲任務等耗時操作)
//非同步呼叫native,mathodPath和params跟同步一樣,callback為收到native非同步執行後的返回結果 function jsCallNative4Asyn(methodPath,params,callback){ dsBridge.call(methodPath,params,callback); }
native呼叫js方法,js需要先進行註冊
//註冊native呼叫js的監聽,functionName為js註冊的標識,callback為通知native端js執行完畢後的結果的回撥 function jsRegisterNative(functionName,callback){ dsBridge.register(functionName,callback) }
js自定義的方法
//非同步呼叫java function getTellerPhoto() { jsCallNative4Asyn("Api.apiAsyn", JSON.stringify({ "controlType": "writeFile", "controlMsg": {"fileName": "test.txt", "fileText": "2222222"} }), function (jsonStr) { alert(jsonStr) }); } //同步呼叫java function connect2Login() { var returnStr = jsCallNative4Syn("Api.apiSyn", JSON.stringify({ "controlType": "writeFile", "controlMsg": {"fileName": "test.txt", "fileText": "2222222"} })); alert(returnStr); } //註冊java呼叫的通知 jsRegisterNative('jsFunction', function (jsonStr) { var j = JSON.parse(jsonStr); var controlType = j.controlType; var controlMsg = j.controlMsg; var jj = JSON.parse(controlMsg); var type = jj.type; var msg = jj.msg; alert("controlType = "+controlType+",controlMsg = "+controlMsg+",type = "+type+",msg = "+msg); return jsonStr; })
具體native流程:
xml中新增webview控制元件
//xml中新增DSJribge的webview控制元件 <com.test.jsbridge.dsbridge.DWebView android:id="@+id/dWebView" android:layout_width="wrap_content" android:layout_height="wrap_content"/>
定義被js呼叫的api
public interface ApiSyn { /** * 同步呼叫 * @param input json格式的引數 */ @JavascriptInterface void apiSyn(Object input); } public interface ApiAsyn { /** * 非同步呼叫 * @param input json格式的引數 * @param handler native給js的回撥通知 */ @JavascriptInterface void apiAsyn(Object input, CompletionHandler handler); }
public class Api implements ApiAsyn, ApiSyn { final String TAG = "Api"; @Override public void apiSyn(Object input) { Log.d(TAG,"js 傳入的引數為 :"+String.valueOf(input)); } @Override public void apiAsyn(Object input, CompletionHandler handler) { Log.d(TAG,"js 傳入的引數為 :"+String.valueOf(input)); try { Thread.sleep(2000); handler.complete("app收到js的入參"); } catch (InterruptedException e) { e.printStackTrace(); } } }
actvity中給webview新增JavaScript工作空間
mDWebView.addJavascriptObject(new Api(),"Api");
java呼叫js方法
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject1 = new JSONObject(); try { jsonObject.put("controlType","java"); jsonObject1.put("type","1"); jsonObject1.put("msg","2"); jsonObject.put("controlMsg",jsonObject1.toString()); String s = jsonObject.toString(); LogUtils.dTag(TAG,"ssss = "+s); JSBridge.callJsFunction(mDWebView,"jsFunction", new Object[]{s}, new OnReturnValue() { @Override public void onValue(Object retValue) { try { LogUtils.dTag(TAG,Convert.toJson(retValue)); } catch (Exception e) { LogUtils.eTag(TAG,retValue); } } }); } catch (JSONException e) { e.printStackTrace(); }