js与native层相互通讯
native->js: WebView.loadUrl() 方法
js->native:
在js中调用window.alert/window.confirm/window.prompt/window.location
WebView中的WebChromeClient将接收到对应的回调信息(onJSAlert/onJSConfirm/onJsPrompt/shouldOverrideUrlLoading)
1. window.alert --> onJSAlert
2. window.confirm --> onJSConfirm
3. window.prompt --> onJsPrompt
4. window.location --> shouldOverrideUrlLoading
由于window.prompt在js中较为少用,我们可以选择window.prompt作为通讯通道.
通讯协议制定(js->native)
js在向native回传信息时,需要js告诉native一些信息以便完成调用操作,
native需要调用某一个类的某个方法,方法需要附带参数.当native完成调用操作时,需要将结果返回给js.
为了区分其他协议,我们制定jsbirdge的scheme为jsbirdge,那么完整的uri如下:
jsbridge://Logger:callbackAddress/log?jsonStr
形如:scheme://className:callbackAddress/methodName?params
通讯协议制定(native->js)
native在返回结果时也需要制定通讯协议,当需要告诉js业务逻辑处理结果的返回值时,需要返回相应的
- 状态码code (1:成功,0:失败,其他异常状态码....)
- 提示消息message ("请求成功"/"业务逻辑异常"...)
- 返回结果值result("...")
同样的,我们将结果封装为json进行返回给js.native 通过调用WebView.loadUrl()方法进行返回.
mWebView.loadUrl("javascript:JSBridge.onFinish(callbackAddress,jsonObj);");
native层代码规范
在native层中,我们使用JSBridge类来统一管理暴露给js的类和方法,并且能够随时新增(或者删除).
JSBridge.register("nameInJs",javaClass.class)
被js调用的类应满足某种规范:
1.类应实现某个接口,约束JSBridge.register方法的第二个参数应该是某一个接口的实现类.
2.类中的方法应该是公共静态方法,并且无返回值.因为返回值会通过回调函数传递给js脚本.
通过以上的规范,类中的方法签名如下
public static void methodName(WebView webview,String jsonParams,Callback callback){}
js层
目前的业务需要,js层至少需要提供以下两个公共方法:
1.封装请求地址[scheme://className:callbackAddress/methodName?params]的方法
2.接收native层回调的方法
1. JSBridge.call(className,methodName,jsonParams,callback)
2. JSBridge.onFinish(callbackAddress,jsonParams)
3. 其他相关的辅助方法
然后调用window.prompt方法将uri传递过去,这时候java层就会收到这个uri,再进一步解析即可
参考链接/扩展阅读:
推荐 Android JSBridge的原理与实现
JSBridge实现原理探索