在Android开发中,能实现Js调用Nactive,有4种方法:
1 | JavascriptInterface |
这里我们讨论下第一种@JavascriptInterface注解实现,和第四种就是WebChromeClient.onJsPrompt() js注入的实现。下面来详细讲解一下二者的使用方式,原理,其他请阅读扩展JsBridge实现JavaScript和Java的互相调用-QQ音乐技术团队。
@JavascriptInterface实现
实现步骤:
- 设置WebView支持js脚本
- 为提供给js调用的方法加上@JavascriptInterface注解
- 给WebView添加js接口
1 | class JsObject { |
- 这种方式不安全,因为这个接口允许JavaScript控制宿主应用程序,在4.2的版本前存在重大安全隐患,JavaScript 可以使用反射访问注入webview的java对象的public fields,在一个包含不信任内容的WebView中使用这个方法,会允许攻击者去篡改宿主应用程序,使用宿主应用程序的权限执行java代码。因此4.2以后,任何为JS暴露的接口,都需要加JavascriptInterface。
- 这种方式当有js回调函数需要android端执行时,都需要将匿名回调函数赋值给全局函数才能供android端回调,增加了js和android端通信的封装层的低效代码量。
Javascript注入实现
先来说说原理吧,当js调用prompt()方法时,WebChromeClient.onJsPrompt()方法会被触发,当js触发Android提供的接口方法时,将该方法的方法名称、参数类型、参数值转成json,然后通过prompt方法传递给android端,android端解析json并通过反射执行对应的方法,同时也支持执行匿名回调。
整个流程比较复杂,看图:
为WebView绑定WebChormeClient监听,在Html加载进度25%时进行js注入(注入的js是根据android提供给js的对象类名动态生成);
动态注入的js代码如下:
1 | javascript: (function(b) { |
代码不难,可以自行理解,其中回调函数被封装在了a对象里面,确保android端可以通过webview.loadUrl()执行回调。
android端回调js代码如下:
1 | javascript:HostApp.callback(0, 0 ,"call back haha"); |
Android提供的每一个js方法都对应一个JsCallback对象,Android就可以通过JsCallback对象来生成并执行回调js的代码。
这种方式通过动态注入js的方式则非常方便,但也有一定限制,比如Android提供的方法必须是static修饰的,且方法第一个参数必须为WebView,不过这不影响使用。