小伙伴们在使用Android原生webview的时候经常会看到js调用Android手机单反、相册或者录音等功能。 后端妹子已经写好了代码功能,在IOS手机上测试没有问题。 它失败了。 Android程序员一定认为自己代码的配置有问题。 经过一段时间的调试,最终发现还是不行。 于是百度和微软终于查到是webview本身的问题(顺便问一下,为什么常用webview?控件,微软优化不了,坑太多了!),好了,不说太多了废话不多说,咱们进入正文。
我们先来说一下什么是JS交互:
说白了,就是后端的一些功能无法调用原生代码,或者在一些复杂的页面和混合页面上,原生页面的速度没有网页快,所以在实际项目中,很多时候都是原生页面和webView混合进行的加载js的网页,这涉及到两者的交互以及传值的问题。
Android调用JS的方式:
JS调用Android方法:
Android调用Js方法
1、将需要测试的js代码放在src/main/asserts文件夹下,测试代码如下
2、配置wevView属性,编写一个测试按钮点击点击
因为是测试,所以我把js代码文件放在asserts中进行加载测试。 实际项目中,就是要加载的链接。 原因是一样的。 点击按钮监听结果:
3、Android调用js方法时,将值传递给js。 有时Android调用js方法时,需要给js传递参数。 我们只需要将参数放入Android端的js方法中即可。 int类型可以直接放进去,string类型转成json然后传给js,如图:
结果显示为:
Android调用js方法时需要注意的事项:
Android调用js的两种方式对比:
JS调用Android方法
1.通过WebView的addJavascriptInterface()
1、js调用Android方法时,需要一个交互桥。 交互桥后端的名称必须与Android给出的名称相同。
2.js代码测试代码为:
3、点击网页中的按钮监听storm,可以看到js已经成功调用了Android的toast方法:
4.优点:使用方便缺点:存在严重漏洞
2、通过WebViewClient的shouldOverrideUrlLoading()进行反弹并拦截url
1. 同意url合约
2、Android端重绘WebViewClient类的shouldOverrideUrlLoading()方法。 评论说的很清楚了,看评论就知道了
3、点击网页中的按钮,js成功调用Android的toast方法,并且参数传递没有问题:
4.优点:没有方法1的漏洞。缺点:获取返回值的方式复杂,需要绑定合约
3、通过WebChromeClient的onJsAlert()、onJsConfirm()、onJsPrompt()方法弹起并拦截JS对话框alert()、confirm()、prompt()方法
常用的拦截是JS输入框(即prompt()方法)。 由于只有prompt()可以返回任意类型的值,所以操作最全面、方便、灵活
1. 同意url合约
2、Android端重写WebChromeClient类中对应的popup方法进行拦截分析
3、可以看到拦截方法和shouldOverrideUrlLoading()是一样的,这里不会出现上图所示的结果
4.优点:无漏洞缺点:获取返回值的方法复杂javascript 调用android,需要绑定合约
Android与JS之间复杂的交互
举个栗子:当JS点击页面上的某个按钮时,需要选择Android手机相册的拍照功能。 选择后,Android程序员需要将图片上传到后台服务器,并在获取网络链接后,通过loadUrl()或evaluateJavascript()方法将图片链接传递给H5端,实现复杂的交互过程。
都说是复杂交互,虽然仍然是简单交互的混合使用javascript 调用android,但只要你了解了简单交互的步骤和价值传递,相信你一定游刃有余。