为了降低开发成本,提高开发效率,目前很多app都是在webview中载入h5页面,即hybrid app。在这种开发模式下,web是如何与native交互的呢?以android为例,为大家分享几种web与native的交互方式。
这里主要为大家分享js调用native的三种方式,以及在项目中是如何使用的?
1、js调用native的方式
方法1:通过Webview的addJavascriptInterface()实现对象映射
- 原理:通过WebView的addJavascriptInterface()给浏览器window对象注入一个命名空间,然后web通过命名空间即可调用native方法 。
- android代码实现
- js代码实现
- 总结
- 虽然使用简单,但android 4.2以下存在严重的。适用于android 4.2以上相对简单的交互场景。
- 产生的原因:当js拿到android对象后,就可以调用这个android对象中的所用方法,包括系统类(java.lang.Runtime类),从而进行任意代码执行。
方法2:通过WebChromeClient的onJsPrompt()/onJsConfirm()/onJsAlert()拦截JS对话框对应方法
- 原理:web通过window对话框传递schema,native拦截schema,如果符合约定scheme,然后分发给native对应的方法去处理。
- schema格式
约定schema格式:jsbridge://xm?arg1=111&arg2=222&arg3=xx
- android代码实现:
- js代码实现
- 总结
- 不存在安全问题,能满足大多数的交互场景。
方法3:通过WebViewClient 的shouldOverrideUrlLoading()拦截url
- 原理:拦截跳转页面的URL,然后对scheme进行解析,如果符合规则就调用native的相应方法进行处理。
- schema格式:jsbridge://xm?arg1=111&arg2=222&arg3=xx
- android代码实现
- js代码实现
- 总结
- 不存在安全问题,适用于不需要返回值情况的互动场景。IOS主要使用该方式。web跳转到native 页面通过url scheme的形式比较方便。
2、项目中如何使用呢?
在js代码中,如果想要这样调用native方法,该如何实现呢?
以方法3为例,即通过WebChromeClient的onJsPrompt()拦截JS window.prompt(),实现对native方法的调用。
- native逻辑流程图:
- js简化实现代码(jsbridge.js)
- android简化实现代码(jsCallNative类中方法)
项目中使用
- js代码
- android代码
3、扩展补充:js与android java通信流程
如需深入研究,可以通过android studio看一下loadUrl和setWebChromeClient两个方法,你会发现其实web view啥都没干,都是直接调用WebViewProvider对应方法处理的,但是aosp(Android Open Source Project)里面并没有WebViewProvider实现类,它的实现类在chromium内核里。可以下载编译一下chromium的源码,追踪一下调用流程,看最终是怎么设置上监听的。