Open yunshuipiao opened 5 years ago
[TOC]
这篇文章介绍 Android 与 js 的交互。由于目前很少有纯 native 的应用,并且电商类 APP 都含有大量的网页,所以这块知识属于必须掌握的。
Android 和 js 交互实际上是通过 WebView 互相调用方法:
那么对于 Android 调用 js 的方法有两种:
而对于 js 调用 android 代码的方式有 3 种:
比较常用,用于加载给定的 url 或者本地 网页,或者执行 js 代码。
// 注意调用的JS方法名要对应上 // 调用javascript的callJS()方法 mWebView.loadUrl("javascript:callJS()");
这里需要注意,JS 代码调用一定要在 onPageFinished() 回调之后, 表示页面加载结束。
该方法比第一种方法效率更高,使用更简洁。
// 只需要将第一种方法的loadUrl()换成下面该方法即可 mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() { @Override public void onReceiveValue(String value) { //此处为 js 返回的结果 } }); }
定义一个与 JS 对象映射关系的 Android 类,AndroidToJs。
// 继承自Object类 public class AndroidtoJs extends Object { // 定义JS需要调用的方法 // 被JS调用的方法必须加入@JavascriptInterface注解 @JavascriptInterface public void hello(String msg) { System.out.println("JS调用了Android的hello方法"); } }
需要调用的 js 代码如下:
function callAndroid(){ // 由于对象映射,所以调用test对象等于调用Android映射的对象 test.hello("js调用了android中的hello方法"); }
在 Android 里面添加对应的映射关系
// 设置与Js交互的权限 webSettings.setJavaScriptEnabled(true); // 通过addJavascriptInterface()将Java对象映射到JS对象 //参数1:Javascript对象名 //参数2:Java对象名 mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS类对象映射到js的test对象
优点:使用简单,仅需要 Android 和 JS 对象的映射。
缺点:当 JS 拿到 Android 这个对象后,就可以调用这个 Android 对象中所有的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行。
如可以执行命令获取本地设备的SD卡中的文件等信息从而造成信息泄露
解决方案:
@JavascriptInterface
具体原理是:
原理:通过 WebViewClient 的 onJsAlert(), onJsConfirm(), onJsPromot() 方法回调分别拦截对应的 JS 对话框。最常见的拦截 promot 对话框。
常用的拦截是:拦截 JS的输入框(即prompt()方法) 因为只有prompt()可以返回任意类型的值,操作最全面方便、更加灵活;而alert()对话框没有返回值;confirm()对话框只能返回两种状态(确定 / 取消)两个值
prompt()
需要返回值时,通过上述 Android 调用 Js 代码将返回值传会 Js 端。
Interaction between Native and js
[TOC]
这篇文章介绍 Android 与 js 的交互。由于目前很少有纯 native 的应用,并且电商类 APP 都含有大量的网页,所以这块知识属于必须掌握的。
交互方式概览
Android 和 js 交互实际上是通过 WebView 互相调用方法:
那么对于 Android 调用 js 的方法有两种:
而对于 js 调用 android 代码的方式有 3 种:
Android 调用 JS
通过 weview 的 loadUrl()
比较常用,用于加载给定的 url 或者本地 网页,或者执行 js 代码。
这里需要注意,JS 代码调用一定要在 onPageFinished() 回调之后, 表示页面加载结束。
通过 webview 的 evaluateJavascript() 方法
该方法比第一种方法效率更高,使用更简洁。
JS 调用 Android 代码
通过 webview.addJavascriptInterface() 进行对象映射
定义一个与 JS 对象映射关系的 Android 类,AndroidToJs。
需要调用的 js 代码如下:
在 Android 里面添加对应的映射关系
优点:使用简单,仅需要 Android 和 JS 对象的映射。
缺点:当 JS 拿到 Android 这个对象后,就可以调用这个 Android 对象中所有的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行。
解决方案:
@JavascriptInterface
进行注解从而避免漏洞攻击通过 webviewClient 的 shouoverrideUrlLoading() 方法回调拦截 url
具体原理是:
通过 WebChromeClient 的方法,自定义协议
原理:通过 WebViewClient 的 onJsAlert(), onJsConfirm(), onJsPromot() 方法回调分别拦截对应的 JS 对话框。最常见的拦截 promot 对话框。
需要返回值时,通过上述 Android 调用 Js 代码将返回值传会 Js 端。