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(); }