为了降低开发成本,提高开发效率,目前很多app都是在webview中载入h5页面,即hybrid app。在这种开发模式下,web是如何与native交互的呢?以android为例,为大家分享几种web与native的交互方式。
![v2-b3651cc839e60c5b0170ddb7df1326fe_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-b3651cc839e60c5b0170ddb7df1326fe_b.jpg)
这里主要为大家分享js调用native的三种方式,以及在项目中是如何使用的?
1、js调用native的方式
方法1:通过Webview的addJavascriptInterface()实现对象映射
- 原理:通过WebView的addJavascriptInterface()给浏览器window对象注入一个命名空间,然后web通过命名空间即可调用native方法 。
![v2-d99b3fc7b1b5292a10a6d980a4e1aee0_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-d99b3fc7b1b5292a10a6d980a4e1aee0_b.jpg)
- android代码实现
![v2-34e152153d67e30cac3e50f56e9bff3a_b.png](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-34e152153d67e30cac3e50f56e9bff3a_b.png)
![v2-abdb405c8ab4785e2b60a22eff826045_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-abdb405c8ab4785e2b60a22eff826045_b.jpg)
- js代码实现
![v2-6fb2b429c619587242b64c1a2ccee82a_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-6fb2b429c619587242b64c1a2ccee82a_b.jpg)
- 总结
- 虽然使用简单,但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对应的方法去处理。
![v2-98a7663e82634443e2928a690cea6734_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-98a7663e82634443e2928a690cea6734_b.jpg)
- schema格式
约定schema格式:jsbridge://xm?arg1=111&arg2=222&arg3=xx
- android代码实现:
![v2-b18cadd71fd4f52205ba9035a43e2194_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-b18cadd71fd4f52205ba9035a43e2194_b.jpg)
- js代码实现
![v2-573410644c544454cdfa6c11712b26ab_b.png](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-573410644c544454cdfa6c11712b26ab_b.png)
- 总结
- 不存在安全漏洞问题,能满足大多数的交互场景。
方法3:通过WebViewClient 的shouldOverrideUrlLoading()拦截url
- 原理:拦截跳转页面的URL,然后对scheme进行解析,如果符合规则就调用native的相应方法进行处理。
![v2-bce62fa738bbfe6b0f8149ffd58ed307_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-bce62fa738bbfe6b0f8149ffd58ed307_b.jpg)
- schema格式:jsbridge://xm?arg1=111&arg2=222&arg3=xx
- android代码实现
![v2-73bb9a597d1b6c567a99f580ac285a4e_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-73bb9a597d1b6c567a99f580ac285a4e_b.jpg)
- js代码实现
![v2-fd6d94915481e1e5c8b0cd0338d330e8_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-fd6d94915481e1e5c8b0cd0338d330e8_b.jpg)
- 总结
- 不存在安全漏洞问题,适用于不需要返回值情况的互动场景。IOS主要使用该方式。web跳转到native 页面通过url scheme的形式比较方便。
2、项目中如何使用呢?
在js代码中,如果想要这样调用native方法,该如何实现呢?
![v2-d71bba6222959c87fb0fb689bfca2ffc_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-d71bba6222959c87fb0fb689bfca2ffc_b.jpg)
以方法3为例,即通过WebChromeClient的onJsPrompt()拦截JS window.prompt(),实现对native方法的调用。
![v2-c78467aa365045adb24d184b88082353_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-c78467aa365045adb24d184b88082353_b.jpg)
- native逻辑流程图:
![v2-861107243ca3a0ae33f1a4bbaa72b409_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-861107243ca3a0ae33f1a4bbaa72b409_b.jpg)
- js简化实现代码(jsbridge.js)
![v2-3f5809c7981a9db579a9ac406dc0d9c2_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-3f5809c7981a9db579a9ac406dc0d9c2_b.jpg)
- android简化实现代码(jsCallNative类中方法)
![v2-4308ff8d78f4b56d68cb9999cbf2ae40_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-4308ff8d78f4b56d68cb9999cbf2ae40_b.jpg)
![v2-d8d179ec8360422cb3a6655df3f49381_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-d8d179ec8360422cb3a6655df3f49381_b.jpg)
项目中使用
-
- js代码
![v2-36ee439785280b76dffd6a3992e3b83f_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-36ee439785280b76dffd6a3992e3b83f_b.jpg)
-
- android代码
![v2-24dc13eae00a5c6c1503a31103de3061_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-24dc13eae00a5c6c1503a31103de3061_b.jpg)
3、扩展补充:js与android java通信流程
![v2-846d03ffa882218f3756be02e145b9f1_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=f3a3a439-2a30-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-846d03ffa882218f3756be02e145b9f1_b.jpg)
如需深入研究,可以通过android studio看一下loadUrl和setWebChromeClient两个方法,你会发现其实web view啥都没干,都是直接调用WebViewProvider对应方法处理的,但是aosp(Android Open Source Project)里面并没有WebViewProvider实现类,它的实现类在chromium内核里。可以下载编译一下chromium的源码,追踪一下调用流程,看最终是怎么设置上监听的。
WebViewChromium类源码,点击这里查看